X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fgeneric-2.6%2Ffiles%2Fcrypto%2Focf%2Fep80579%2Ficp_common.c;fp=target%2Flinux%2Fgeneric-2.6%2Ffiles%2Fcrypto%2Focf%2Fep80579%2Ficp_common.c;h=5d46c0adc671a8f8ba3d2cc1afb9d6a046838076;hb=5ac40cd7d53751d8d9d8b6896c6072b94b6cbbaf;hp=461370c2c7c83c6170bf5b5a1b2d662930f048aa;hpb=c88d9d7309673e300b610deeca74e241f88e8b93;p=openwrt%2Fsvn-archive%2Farchive.git diff --git a/target/linux/generic-2.6/files/crypto/ocf/ep80579/icp_common.c b/target/linux/generic-2.6/files/crypto/ocf/ep80579/icp_common.c index 461370c2c7..5d46c0adc6 100644 --- a/target/linux/generic-2.6/files/crypto/ocf/ep80579/icp_common.c +++ b/target/linux/generic-2.6/files/crypto/ocf/ep80579/icp_common.c @@ -1,11 +1,11 @@ -/*************************************************************************** +/************************************************************************* * * This file is provided under a dual BSD/GPLv2 license. When using or * redistributing this file, you may do so under either license. * * GPL LICENSE SUMMARY * - * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -27,7 +27,7 @@ * * BSD LICENSE * - * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,7 +57,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * - * version: Security.L.1.0.130 + * version: Security.L.1.0.2-229 * ***************************************************************************/ @@ -71,38 +71,57 @@ #include "icp_ocf.h" -#define ICP_OCF_COMP_NAME "ICP_OCF" -#define ICP_OCF_VER_MAIN (2) -#define ICP_OCF_VER_MJR (0) -#define ICP_OCF_VER_MNR (0) +#define ICP_OCF_COMP_NAME "ICP_OCF" +#define ICP_OCF_VER_MAIN (2) +#define ICP_OCF_VER_MJR (1) +#define ICP_OCF_VER_MNR (0) -#define MAX_DEREG_RETRIES (100) +#define MAX_DEREG_RETRIES (100) #define DEFAULT_DEREG_RETRIES (10) #define DEFAULT_DEREG_DELAY_IN_JIFFIES (10) /* This defines the maximum number of sessions possible between OCF - and the OCF Tolapai Driver. If set to zero, there is no limit. */ -#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0) -#define NUM_SUPPORTED_CAPABILITIES (21) + and the OCF EP80579 Driver. If set to zero, there is no limit. */ +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0) +#define NUM_SUPPORTED_CAPABILITIES (21) + +/*Slab zone names*/ +#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat" +#define ICP_OP_DATA_NAME "icp_ocf.OpDat" +#define ICP_DH_NAME "icp_ocf.DH" +#define ICP_MODEXP_NAME "icp_ocf.ModExp" +#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec" +#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk" +#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg" +#define ICP_DSA_VER_NAME "icp_ocf.DSAver" +#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd" +#define ICP_FLAT_BUFF_NAME "icp_ocf.FB" /*Slabs zones*/ -struct kmem_cache *drvSessionData_zone = NULL; -struct kmem_cache *drvOpData_zone = NULL; -struct kmem_cache *drvDH_zone = NULL; -struct kmem_cache *drvLnModExp_zone = NULL; -struct kmem_cache *drvRSADecrypt_zone = NULL; -struct kmem_cache *drvRSAPrivateKey_zone = NULL; -struct kmem_cache *drvDSARSSign_zone = NULL; -struct kmem_cache *drvDSARSSignKValue_zone = NULL; -struct kmem_cache *drvDSAVerify_zone = NULL; +icp_kmem_cache drvSessionData_zone = NULL; +icp_kmem_cache drvOpData_zone = NULL; +icp_kmem_cache drvDH_zone = NULL; +icp_kmem_cache drvLnModExp_zone = NULL; +icp_kmem_cache drvRSADecrypt_zone = NULL; +icp_kmem_cache drvRSAPrivateKey_zone = NULL; +icp_kmem_cache drvDSARSSign_zone = NULL; +icp_kmem_cache drvDSARSSignKValue_zone = NULL; +icp_kmem_cache drvDSAVerify_zone = NULL; /*Slab zones for flatbuffers and bufferlist*/ -struct kmem_cache *drvFlatBuffer_zone = NULL; +icp_kmem_cache drvFlatBuffer_zone = NULL; -static int icp_ocfDrvInit(void); -static void icp_ocfDrvExit(void); +static inline int icp_cache_null_check(void) +{ + return (drvSessionData_zone && drvOpData_zone + && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone + && drvRSAPrivateKey_zone && drvDSARSSign_zone + && drvDSARSSign_zone && drvDSARSSignKValue_zone + && drvDSAVerify_zone && drvFlatBuffer_zone); +} + +/*Function to free all allocated slab caches before exiting the module*/ static void icp_ocfDrvFreeCaches(void); -static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg); int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID; @@ -115,66 +134,42 @@ int num_dereg_retries = DEFAULT_DEREG_RETRIES; int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES; /* Module parameter - gives the maximum number of sessions possible between - OCF and the OCF Tolapai Driver. If set to zero, there is no limit.*/ + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/ int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT; /* This is set when the module is removed from the system, no further processing can take place if this is set */ -atomic_t icp_ocfDrvIsExiting = ATOMIC_INIT(0); +icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0); /* This is used to show how many lac sessions were not deregistered*/ -atomic_t lac_session_failed_dereg_count = ATOMIC_INIT(0); +icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0); /* This is used to track the number of registered sessions between OCF and - * and the OCF Tolapai driver, when max_session is set to value other than + * and the OCF EP80579 driver, when max_session is set to value other than * zero. This ensures that the max_session set for the OCF and the driver * is equal to the LAC registered sessions */ -atomic_t num_ocf_to_drv_registered_sessions = ATOMIC_INIT(0); +icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0); /* Head of linked list used to store session data */ -struct list_head icp_ocfDrvGlobalSymListHead; -struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList; +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead; +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList; -spinlock_t icp_ocfDrvSymSessInfoListSpinlock = SPIN_LOCK_UNLOCKED; -rwlock_t icp_kmem_cache_destroy_alloc_lock = RW_LOCK_UNLOCKED; +icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock; -struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ; +/*Below pointer is only used in linux, FreeBSD uses the name to +create its own variable name*/ +icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL; +ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ); struct icp_drvBuffListInfo defBuffListInfo; -static struct { - softc_device_decl sc_dev; -} icpDev; - -static device_method_t icp_methods = { - /* crypto device methods */ - DEVMETHOD(cryptodev_newsession, icp_ocfDrvNewSession), - DEVMETHOD(cryptodev_freesession, icp_ocfDrvFreeLACSession), - DEVMETHOD(cryptodev_process, icp_ocfDrvSymProcess), - DEVMETHOD(cryptodev_kprocess, icp_ocfDrvPkeProcess), -}; - -module_param(num_dereg_retries, int, S_IRUGO); -module_param(dereg_retry_delay_in_jiffies, int, S_IRUGO); -module_param(max_sessions, int, S_IRUGO); - -MODULE_PARM_DESC(num_dereg_retries, - "Number of times to retry LAC Sym Session Deregistration. " - "Default 10, Max 100"); -MODULE_PARM_DESC(dereg_retry_delay_in_jiffies, "Delay in jiffies " - "(added to a schedule() function call) before a LAC Sym " - "Session Dereg is retried. Default 10"); -MODULE_PARM_DESC(max_sessions, "This sets the maximum number of sessions " - "between OCF and this driver. If this value is set to zero, " - "max session count checking is disabled. Default is zero(0)"); - /* Name : icp_ocfDrvInit * * Description : This function will register all the symmetric and asymmetric * functionality that will be accelerated by the hardware. It will also * get a unique driver ID from the OCF and initialise all slab caches */ -static int __init icp_ocfDrvInit(void) +ICP_MODULE_INIT_FUNC(icp_ocfDrvInit) { int ocfStatus = 0; @@ -184,7 +179,7 @@ static int __init icp_ocfDrvInit(void) if (MAX_DEREG_RETRIES < num_dereg_retries) { EPRINTK("Session deregistration retry count set to greater " "than %d", MAX_DEREG_RETRIES); - return -1; + icp_module_return_code(EINVAL); } /* Initialize and Start the Cryptographic component */ @@ -192,130 +187,133 @@ static int __init icp_ocfDrvInit(void) cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) { EPRINTK("Failed to initialize and start the instance " "of the Cryptographic component.\n"); - return -1; + return icp_module_return_code(EINVAL); } + icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock); + /* Set the default size of BufferList to allocate */ memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo)); if (ICP_OCF_DRV_STATUS_SUCCESS != icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS, &defBuffListInfo)) { EPRINTK("Failed to get bufferlist memory info.\n"); - return -1; + return icp_module_return_code(ENOMEM); } - /*Register OCF Tolapai Driver with OCF */ - memset(&icpDev, 0, sizeof(icpDev)); - softc_device_init(&icpDev, "icp", 0, icp_methods); - - icp_ocfDrvDriverId = crypto_get_driverid(softc_get_device(&icpDev), - CRYPTOCAP_F_HARDWARE); + /*Register OCF EP80579 Driver with OCF */ + icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID(); if (icp_ocfDrvDriverId < 0) { EPRINTK("%s : ICP driver failed to register with OCF!\n", __FUNCTION__); - return -ENODEV; + return icp_module_return_code(ENODEV); } - /*Create all the slab caches used by the OCF Tolapai Driver */ + /*Create all the slab caches used by the OCF EP80579 Driver */ drvSessionData_zone = - ICP_CACHE_CREATE("ICP Session Data", struct icp_drvSessionData); - ICP_CACHE_NULL_CHECK(drvSessionData_zone); + ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData); /* * Allocation of the OpData includes the allocation space for meta data. * The memory after the opData structure is reserved for this meta data. */ drvOpData_zone = - kmem_cache_create("ICP Op Data", sizeof(struct icp_drvOpData) + - defBuffListInfo.metaSize ,0, SLAB_HWCACHE_ALIGN, NULL, NULL); + icp_kmem_cache_create(ICP_OP_DATA_NAME, + sizeof(struct icp_drvOpData) + + defBuffListInfo.metaSize, + ICP_KERNEL_CACHE_ALIGN, + ICP_KERNEL_CACHE_NOINIT); - - ICP_CACHE_NULL_CHECK(drvOpData_zone); - - drvDH_zone = ICP_CACHE_CREATE("ICP DH data", CpaCyDhPhase1KeyGenOpData); - ICP_CACHE_NULL_CHECK(drvDH_zone); + drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData); drvLnModExp_zone = - ICP_CACHE_CREATE("ICP ModExp data", CpaCyLnModExpOpData); - ICP_CACHE_NULL_CHECK(drvLnModExp_zone); + ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData); drvRSADecrypt_zone = - ICP_CACHE_CREATE("ICP RSA decrypt data", CpaCyRsaDecryptOpData); - ICP_CACHE_NULL_CHECK(drvRSADecrypt_zone); + ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData); drvRSAPrivateKey_zone = - ICP_CACHE_CREATE("ICP RSA private key data", CpaCyRsaPrivateKey); - ICP_CACHE_NULL_CHECK(drvRSAPrivateKey_zone); + ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey); drvDSARSSign_zone = - ICP_CACHE_CREATE("ICP DSA Sign", CpaCyDsaRSSignOpData); - ICP_CACHE_NULL_CHECK(drvDSARSSign_zone); + ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData); /*too awkward to use a macro here */ drvDSARSSignKValue_zone = - kmem_cache_create("ICP DSA Sign Rand Val", - DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES, 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - ICP_CACHE_NULL_CHECK(drvDSARSSignKValue_zone); + ICP_CACHE_CREATE(ICP_RAND_VAL_NAME, + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES); drvDSAVerify_zone = - ICP_CACHE_CREATE("ICP DSA Verify", CpaCyDsaVerifyOpData); - ICP_CACHE_NULL_CHECK(drvDSAVerify_zone); + ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData); drvFlatBuffer_zone = - ICP_CACHE_CREATE("ICP Flat Buffers", CpaFlatBuffer); - ICP_CACHE_NULL_CHECK(drvFlatBuffer_zone); + ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer); + + if (0 == icp_cache_null_check()) { + icp_ocfDrvFreeCaches(); + EPRINTK("%s() line %d: Not enough memory!\n", + __FUNCTION__, __LINE__); + return ENOMEM; + } /* Register the ICP symmetric crypto support. */ - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_NULL_CBC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_DES_CBC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_3DES_CBC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_AES_CBC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_ARC4); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5_HMAC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1_HMAC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256_HMAC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384_HMAC); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512); - ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512_HMAC); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC, + ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC, + ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus); + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC, + ocfStatus); /* Register the ICP asymmetric algorithm support */ - ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DH_COMPUTE_KEY); - ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP); - ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP_CRT); - ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_SIGN); - ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_VERIFY); + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY, + ocfStatus); + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus); + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus); + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus); + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus); /* Register the ICP random number generator support */ - if (OCF_REGISTRATION_STATUS_SUCCESS == - crypto_rregister(icp_ocfDrvDriverId, icp_ocfDrvReadRandom, NULL)) { - ocfStatus++; - } + ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId, + icp_ocfDrvReadRandom, NULL, ocfStatus); if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) { DPRINTK("%s: Failed to register any device capabilities\n", __FUNCTION__); icp_ocfDrvFreeCaches(); icp_ocfDrvDriverId = INVALID_DRIVER_ID; - return -ECANCELED; + return icp_module_return_code(ECANCELED); } DPRINTK("%s: Registered %d of %d device capabilities\n", __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES); -/*Session data linked list used during module exit*/ - INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead); - INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList); + /*Session data linked list used during module exit */ + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead); + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList); - icp_ocfDrvFreeLacSessionWorkQ = - create_singlethread_workqueue("ocfLacDeregWorkQueue"); + ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq"); + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) { + EPRINTK("%s: Failed to create single " + "thread workqueue\n", __FUNCTION__); + icp_ocfDrvFreeCaches(); + icp_ocfDrvDriverId = INVALID_DRIVER_ID; + return icp_module_return_code(ENOMEM); + } - return 0; + return icp_module_return_code(0); } /* Name : icp_ocfDrvExit @@ -325,31 +323,46 @@ static int __init icp_ocfDrvInit(void) * and asymmetric functionality that can be accelerated by the hardware via OCF * and random number generation if it is enabled. */ -static void icp_ocfDrvExit(void) +ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit) { CpaStatus lacStatus = CPA_STATUS_SUCCESS; struct icp_drvSessionData *sessionData = NULL; struct icp_drvSessionData *tempSessionData = NULL; int i, remaining_delay_time_in_jiffies = 0; + + /* For FreeBSD the invariant macro below makes function to return */ + /* with EBUSY value in the case of any session which has been regi- */ + /* stered with LAC not being deregistered. */ + /* The Linux implementation is empty since it is purely to compensate */ + /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */ + + ICP_MODULE_EXIT_INV(); + /* There is a possibility of a process or new session command being */ /* sent before this variable is incremented. The aim of this variable */ /* is to stop a loop of calls creating a deadlock situation which */ /* would prevent the driver from exiting. */ - - atomic_inc(&icp_ocfDrvIsExiting); + icp_atomic_set(&icp_ocfDrvIsExiting, 1); /*Existing sessions will be routed to another driver after these calls */ crypto_unregister_all(icp_ocfDrvDriverId); crypto_runregister_all(icp_ocfDrvDriverId); + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) { + DPRINTK("%s: workqueue already " + "destroyed, therefore module exit " + " function already called. Exiting.\n", __FUNCTION__); + return ICP_MODULE_EXIT_FUNC_RETURN_VAL; + } /*If any sessions are waiting to be deregistered, do that. This also flushes the work queue */ - destroy_workqueue(icp_ocfDrvFreeLacSessionWorkQ); + ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ); /*ENTER CRITICAL SECTION */ - spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock); - list_for_each_entry_safe(tempSessionData, sessionData, - &icp_ocfDrvGlobalSymListHead, listNode) { + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock); + + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData, + &icp_ocfDrvGlobalSymListHead, listNode) { for (i = 0; i < num_dereg_retries; i++) { /*No harm if bad input - LAC will handle error cases */ if (ICP_SESSION_RUNNING == tempSessionData->inUse) { @@ -361,7 +374,7 @@ static void icp_ocfDrvExit(void) /* Succesfully deregistered */ break; } else if (CPA_STATUS_RETRY != lacStatus) { - atomic_inc + icp_atomic_inc (&lac_session_failed_dereg_count); break; } @@ -372,8 +385,9 @@ static void icp_ocfDrvExit(void) dereg_retry_delay_in_jiffies; while (0 > remaining_delay_time_in_jiffies) { remaining_delay_time_in_jiffies = - schedule_timeout - (remaining_delay_time_in_jiffies); + icp_schedule_timeout + (&icp_ocfDrvSymSessInfoListSpinlock, + remaining_delay_time_in_jiffies); } DPRINTK @@ -383,44 +397,48 @@ static void icp_ocfDrvExit(void) } /*remove from current list */ - list_del(&(tempSessionData->listNode)); + ICP_LIST_DEL(tempSessionData, listNode); /*add to free mem linked list */ - list_add(&(tempSessionData->listNode), - &icp_ocfDrvGlobalSymListHead_FreeMemList); + ICP_LIST_ADD(tempSessionData, + &icp_ocfDrvGlobalSymListHead_FreeMemList, + listNode); } /*EXIT CRITICAL SECTION */ - spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock); + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock); /*set back to initial values */ sessionData = NULL; /*still have a reference in our list! */ tempSessionData = NULL; /*free memory */ - list_for_each_entry_safe(tempSessionData, sessionData, - &icp_ocfDrvGlobalSymListHead_FreeMemList, - listNode) { - list_del(&(tempSessionData->listNode)); + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData, + &icp_ocfDrvGlobalSymListHead_FreeMemList, + listNode) { + + ICP_LIST_DEL(tempSessionData, listNode); /* Free allocated CpaCySymSessionCtx */ if (NULL != tempSessionData->sessHandle) { - kfree(tempSessionData->sessHandle); + icp_kfree(tempSessionData->sessHandle); } memset(tempSessionData, 0, sizeof(struct icp_drvSessionData)); - kmem_cache_free(drvSessionData_zone, tempSessionData); + ICP_CACHE_FREE(drvSessionData_zone, tempSessionData); } - if (0 != atomic_read(&lac_session_failed_dereg_count)) { + if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) { DPRINTK("%s(): %d LAC sessions were not deregistered " "correctly. This is not a clean exit! \n", __FUNCTION__, - atomic_read(&lac_session_failed_dereg_count)); + icp_atomic_read(&lac_session_failed_dereg_count)); } icp_ocfDrvFreeCaches(); icp_ocfDrvDriverId = INVALID_DRIVER_ID; + icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock); + /* Shutdown the Cryptographic component */ lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE); if (CPA_STATUS_SUCCESS != lacStatus) { @@ -429,6 +447,7 @@ static void icp_ocfDrvExit(void) __FUNCTION__, lacStatus); } + return ICP_MODULE_EXIT_FUNC_RETURN_VAL; } /* Name : icp_ocfDrvFreeCaches @@ -437,9 +456,7 @@ static void icp_ocfDrvExit(void) */ static void icp_ocfDrvFreeCaches(void) { - if (atomic_read(&icp_ocfDrvIsExiting) != CPA_TRUE) { - atomic_set(&icp_ocfDrvIsExiting, 1); - } + icp_atomic_set(&icp_ocfDrvIsExiting, 1); /*Sym Zones */ ICP_CACHE_DESTROY(drvSessionData_zone); @@ -465,7 +482,6 @@ static void icp_ocfDrvFreeCaches(void) * off to a work queue. If it fails, nothing more can be done and it * returns an error */ - int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister) { struct icp_ocfDrvFreeLacSession *workstore = NULL; @@ -475,11 +491,11 @@ int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister) /*make sure the session is not available to be allocated during this process */ - atomic_inc(&lac_session_failed_dereg_count); + icp_atomic_inc(&lac_session_failed_dereg_count); /*Farm off to work queue */ workstore = - kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), GFP_ATOMIC); + icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT); if (NULL == workstore) { DPRINTK("%s(): unable to free session - no memory available " "for work queue\n", __FUNCTION__); @@ -488,9 +504,11 @@ int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister) workstore->sessionToDeregister = sessionToDeregister; - INIT_WORK(&(workstore->work), icp_ocfDrvDeferedFreeLacSessionProcess, - workstore); - queue_work(icp_ocfDrvFreeLacSessionWorkQ, &(workstore->work)); + icp_init_work(&(workstore->work), + icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore); + + ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ, + &(workstore->work)); return ICP_OCF_DRV_STATUS_SUCCESS; @@ -503,7 +521,7 @@ int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister) * CPA_STATUS_RETRY message from the LAC component. This function is run in * Thread context because it is called from a worker thread */ -static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg) +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg) { struct icp_ocfDrvFreeLacSession *workstore = NULL; CpaCySymSessionCtx sessionToDeregister = NULL; @@ -519,10 +537,10 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg) } sessionToDeregister = workstore->sessionToDeregister; - kfree(workstore); + icp_kfree(workstore); /*if exiting, give deregistration one more blast only */ - if (atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) { + if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) { lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE, sessionToDeregister); @@ -533,7 +551,7 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg) return; } - atomic_dec(&lac_session_failed_dereg_count); + icp_atomic_dec(&lac_session_failed_dereg_count); return; } @@ -542,7 +560,7 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg) sessionToDeregister); if (lacStatus == CPA_STATUS_SUCCESS) { - atomic_dec(&lac_session_failed_dereg_count); + icp_atomic_dec(&lac_session_failed_dereg_count); return; } if (lacStatus != CPA_STATUS_RETRY) { @@ -554,16 +572,17 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg) /*schedule_timout returns the time left for completion if this task is set to TASK_INTERRUPTIBLE */ remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies; - while (0 > remaining_delay_time_in_jiffies) { + while (0 < remaining_delay_time_in_jiffies) { remaining_delay_time_in_jiffies = - schedule_timeout(remaining_delay_time_in_jiffies); + icp_schedule_timeout(NULL, + remaining_delay_time_in_jiffies); } } DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__); DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__, - atomic_read(&lac_session_failed_dereg_count)); + icp_atomic_read(&lac_session_failed_dereg_count)); } /* Name : icp_ocfDrvPtrAndLenToFlatBuffer @@ -581,131 +600,6 @@ icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len, pFlatBuffer->dataLenInBytes = len; } -/* Name : icp_ocfDrvSingleSkBuffToFlatBuffer - * - * Description : This function converts a single socket buffer (sk_buff) - * structure to a Fredericksburg Flat Buffer (CpaFlatBuffer) format. - * - * This function assumes that the data passed in are valid. - */ -static inline void -icp_ocfDrvSingleSkBuffToFlatBuffer(struct sk_buff *pSkb, - CpaFlatBuffer * pFlatBuffer) -{ - pFlatBuffer->pData = pSkb->data; - pFlatBuffer->dataLenInBytes = skb_headlen(pSkb); -} - -/* Name : icp_ocfDrvSkBuffToBufferList - * - * Description : This function converts a socket buffer (sk_buff) structure to - * Fredericksburg Scatter/Gather (CpaBufferList) buffer format. - * - * This function assumes that the bufferlist has been allocated with the correct - * number of buffer arrays. - * - */ -inline int -icp_ocfDrvSkBuffToBufferList(struct sk_buff *pSkb, CpaBufferList * bufferList) -{ - CpaFlatBuffer *curFlatBuffer = NULL; - char *skbuffPageAddr = NULL; - struct sk_buff *pCurFrag = NULL; - struct skb_shared_info *pShInfo = NULL; - uint32_t page_offset = 0, i = 0; - - DPRINTK("%s(): Entry Point\n", __FUNCTION__); - - /* - * In all cases, the first skb needs to be translated to FlatBuffer. - * Perform a buffer translation for the first skbuff - */ - curFlatBuffer = bufferList->pBuffers; - icp_ocfDrvSingleSkBuffToFlatBuffer(pSkb, curFlatBuffer); - - /* Set the userData to point to the original sk_buff */ - bufferList->pUserData = (void *)pSkb; - - /* We now know we'll have at least one element in the SGL */ - bufferList->numBuffers = 1; - - if (0 == skb_is_nonlinear(pSkb)) { - /* Is a linear buffer - therefore it's a single skbuff */ - DPRINTK("%s(): Exit Point\n", __FUNCTION__); - return ICP_OCF_DRV_STATUS_SUCCESS; - } - - curFlatBuffer++; - pShInfo = skb_shinfo(pSkb); - if (pShInfo->frag_list != NULL && pShInfo->nr_frags != 0) { - EPRINTK("%s():" - "Translation for a combination of frag_list " - "and frags[] array not supported!\n", __FUNCTION__); - return ICP_OCF_DRV_STATUS_FAIL; - } else if (pShInfo->frag_list != NULL) { - /* - * Non linear skbuff supported through frag_list - * Perform translation for each fragment (sk_buff) - * in the frag_list of the first sk_buff. - */ - for (pCurFrag = pShInfo->frag_list; - pCurFrag != NULL; pCurFrag = pCurFrag->next) { - icp_ocfDrvSingleSkBuffToFlatBuffer(pCurFrag, - curFlatBuffer); - curFlatBuffer++; - bufferList->numBuffers++; - } - } else if (pShInfo->nr_frags != 0) { - /* - * Perform translation for each fragment in frags array - * and add to the BufferList - */ - for (i = 0; i < pShInfo->nr_frags; i++) { - /* Get the page address and offset of this frag */ - skbuffPageAddr = (char *)pShInfo->frags[i].page; - page_offset = pShInfo->frags[i].page_offset; - - /* Convert a pointer and length to a flat buffer */ - icp_ocfDrvPtrAndLenToFlatBuffer(skbuffPageAddr + - page_offset, - pShInfo->frags[i].size, - curFlatBuffer); - curFlatBuffer++; - bufferList->numBuffers++; - } - } else { - EPRINTK("%s():" "Could not recognize skbuff fragments!\n", - __FUNCTION__); - return ICP_OCF_DRV_STATUS_FAIL; - } - - DPRINTK("%s(): Exit Point\n", __FUNCTION__); - return ICP_OCF_DRV_STATUS_SUCCESS; -} - -/* Name : icp_ocfDrvBufferListToSkBuff - * - * Description : This function converts a Fredericksburg Scatter/Gather - * (CpaBufferList) buffer format to socket buffer structure. - */ -inline int -icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList, struct sk_buff **skb) -{ - DPRINTK("%s(): Entry Point\n", __FUNCTION__); - - /* Retrieve the orignal skbuff */ - *skb = (struct sk_buff *)bufferList->pUserData; - if (NULL == *skb) { - EPRINTK("%s():" - "Error on converting from a BufferList. " - "The BufferList does not contain an sk_buff.\n", - __FUNCTION__); - return ICP_OCF_DRV_STATUS_FAIL; - } - DPRINTK("%s(): Exit Point\n", __FUNCTION__); - return ICP_OCF_DRV_STATUS_SUCCESS; -} - /* Name : icp_ocfDrvPtrAndLenToBufferList * * Description : This function converts a "pointer and length" buffer @@ -761,45 +655,6 @@ icp_ocfDrvBufferListMemInfo(uint16_t numBuffers, return ICP_OCF_DRV_STATUS_SUCCESS; } -/* Name : icp_ocfDrvGetSkBuffFrags - * - * Description : This function will determine the number of - * fragments in a socket buffer(sk_buff). - */ -inline uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff * pSkb) -{ - uint16_t numFrags = 0; - struct sk_buff *pCurFrag = NULL; - struct skb_shared_info *pShInfo = NULL; - - if (NULL == pSkb) - return 0; - - numFrags = 1; - if (0 == skb_is_nonlinear(pSkb)) { - /* Linear buffer - it's a single skbuff */ - return numFrags; - } - - pShInfo = skb_shinfo(pSkb); - if (NULL != pShInfo->frag_list && 0 != pShInfo->nr_frags) { - EPRINTK("%s(): Combination of frag_list " - "and frags[] array not supported!\n", __FUNCTION__); - return 0; - } else if (0 != pShInfo->nr_frags) { - numFrags += pShInfo->nr_frags; - return numFrags; - } else if (NULL != pShInfo->frag_list) { - for (pCurFrag = pShInfo->frag_list; - pCurFrag != NULL; pCurFrag = pCurFrag->next) { - numFrags++; - } - return numFrags; - } else { - return 0; - } -} - /* Name : icp_ocfDrvFreeFlatBuffer * * Description : This function will deallocate flat buffer. @@ -808,7 +663,7 @@ inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer) { if (pFlatBuffer != NULL) { memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer)); - kmem_cache_free(drvFlatBuffer_zone, pFlatBuffer); + ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer); } } @@ -819,14 +674,14 @@ inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer) */ inline int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList, - const struct icp_drvOpData *pOpData) + struct icp_drvOpData *pOpData) { Cpa32U metaSize = 0; - if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS){ - void *pOpDataStartAddr = (void *)pOpData; + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) { + uint8_t *pOpDataStartAddr = (uint8_t *) pOpData; - if (0 == defBuffListInfo.metaSize) { + if (0 == defBuffListInfo.metaSize) { pBufferList->pPrivateMetaData = NULL; return ICP_OCF_DRV_STATUS_SUCCESS; } @@ -835,8 +690,9 @@ icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList, * op data. It has been pre-allocated in memory just after the * icp_drvOpData structure. */ - pBufferList->pPrivateMetaData = pOpDataStartAddr + - sizeof(struct icp_drvOpData); + pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr + + sizeof(struct + icp_drvOpData)); } else { if (CPA_STATUS_SUCCESS != cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE, @@ -852,7 +708,8 @@ icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList, return ICP_OCF_DRV_STATUS_SUCCESS; } - pBufferList->pPrivateMetaData = kmalloc(metaSize, GFP_ATOMIC); + pBufferList->pPrivateMetaData = + icp_kmalloc(metaSize, ICP_M_NOWAIT); } if (NULL == pBufferList->pPrivateMetaData) { EPRINTK("%s() Failed to allocate pPrivateMetaData.\n", @@ -879,13 +736,38 @@ inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList) * Otherwise, the meta data shall be freed when the icp_drvOpData is * freed. */ - if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers){ - kfree(pBufferList->pPrivateMetaData); + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) { + icp_kfree(pBufferList->pPrivateMetaData); } } -module_init(icp_ocfDrvInit); -module_exit(icp_ocfDrvExit); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_AUTHOR("Intel"); -MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration"); +/* Module declaration, init and exit functions */ +ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit); +ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration"); +ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR); +ICP_MODULE_LICENSE("Dual BSD/GPL"); +ICP_MODULE_AUTHOR("Intel"); + +/* Module parameters */ +ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries, + "Number of times to retry LAC Sym Session Deregistration. " + "Default 10, Max 100"); +ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies " + "(added to a schedule() function call) before a LAC Sym " + "Session Dereg is retried. Default 10"); +ICP_MODULE_PARAM_INT(icp_ocf, max_sessions, + "This sets the maximum number of sessions " + "between OCF and this driver. If this value is set to zero," + "max session count checking is disabled. Default is zero(0)"); + +/* Module dependencies */ +#define MODULE_MIN_VER 1 +#define CRYPTO_MAX_VER 3 +#define LAC_MAX_VER 2 + +ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER, + CRYPTO_MAX_VER); +ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER, + CRYPTO_MAX_VER); +ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER, + LAC_MAX_VER);