⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssx31apke.c

📁 海思KEY驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/errno.h>

#include <linux/slab.h>
#include <linux/delay.h>


#include "../def.h"
#include "SSX31ADrv.h"
#include "SSX31APke.h"

/*****************************************************MOD****************************************************************************/
/*****************************************************MOD****************************************************************************/
/*****************************************************MOD****************************************************************************/

ULONG SSX31A_SetBDDstModDouble(PEBD_DESC * pCurBD, UCHAR* pcRes, ULONG ulResLen, UCHAR* pcRes1, ULONG ulRes1Len)
{
	SSX31A_OCD* pScatterDesc = NULL;
	ULONG* ulTmp;

    pScatterDesc = (SSX31A_OCD*)Malloc( 2 * sizeof(SSX31A_OCD) );

	
    if (pScatterDesc == NULL)
    {
#ifdef HI_DBG    
        PRINT("SSX31A driver PE send mem alloc fail\r\n");
#endif	
        return ERR;                               
    }

    pCurBD->ulOutputContext  = (ULONG)virt_to_bus(pScatterDesc);  
    pCurBD->ulOutputNum = 2;
    pCurBD->ulOutputLength0= ulResLen + ulRes1Len;
    pCurBD->ulScatterEnable = BD_SCATTER_ENABLE;
  
	pScatterDesc->ulOutputPtr = (ULONG)virt_to_bus(pcRes);
	pScatterDesc->ulOutputLen = ulResLen;
	pScatterDesc->ulOutputAttrib = ICD_ATTRIB_LAST_PART;
	pScatterDesc->ulOrig = 0;
		
	pScatterDesc ++;
	pScatterDesc->ulOutputPtr = (ULONG)virt_to_bus(pcRes1);
	pScatterDesc->ulOutputLen = ulRes1Len;
	pScatterDesc->ulOutputAttrib = ICD_ATTRIB_LAST_PART;
	pScatterDesc->ulOrig = 0;
	
	return OK;
}

ULONG SSX31A_SetBDSrcModDouble(PEBD_DESC * pCurBD, UCHAR* pcModulusN, ULONG ulModulusNLen, UCHAR* pcA, ULONG ulALen, UCHAR* pcB, ULONG
ulBLen, UCHAR* pcModulusN1, ULONG ulModulusN1Len, UCHAR* pcA1, ULONG ulA1Len, UCHAR* pcB1, ULONG ulB1Len)
{
	SSX31A_ICD* pGatherDesc = NULL;
	int i;
	ULONG* ulTmp;
	
    pGatherDesc = (SSX31A_ICD*)Malloc( 6 * sizeof(SSX31A_ICD) );

	
    if (pGatherDesc == NULL)
    {
#ifdef HI_DBG    
        PRINT("SSX31A driver PE send mem alloc fail\r\n");
#endif	
        return ERR;                               
    }

    pCurBD->ulInputContext  = (ULONG)virt_to_bus(pGatherDesc);  
    pCurBD->ulInputNum = 6;
    pCurBD->ulInputLength= ulModulusNLen + ulALen + ulBLen + ulModulusN1Len + ulA1Len + ulB1Len;
    pCurBD->ulGatherEnable = BD_GATHER_ENABLE;

  
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcModulusN);
	pGatherDesc->ulInputLen = ulModulusNLen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;

	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcModulusN1);
	pGatherDesc->ulInputLen = ulModulusN1Len;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;

		
	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcB);
	pGatherDesc->ulInputLen = ulBLen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;

	
	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcB1);
	pGatherDesc->ulInputLen = ulB1Len;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;

		
		
	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcA);
	pGatherDesc->ulInputLen = ulALen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;

		
		
	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcA1);
	pGatherDesc->ulInputLen = ulA1Len;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;


	

	
	return OK;	
}

ULONG SSX31A_SetBDSrcModGet(PEBD_DESC * pCurBD, UCHAR* pcModulusN, ULONG ulModulusNLen, UCHAR* pcA, ULONG ulALen)
{
	SSX31A_ICD* pGatherDesc = NULL;

    pGatherDesc = (SSX31A_ICD*)Malloc( 2 * sizeof(SSX31A_ICD) );

	
    if (pGatherDesc == NULL)
    {
#ifdef HI_DBG    
        PRINT("SSX31A driver PE send mem alloc fail\r\n");
#endif	
        return ERR;                               
    }

    pCurBD->ulInputContext  = (ULONG)virt_to_bus(pGatherDesc);  
    pCurBD->ulInputNum = 2;
    pCurBD->ulInputLength= ulModulusNLen + ulALen;
    pCurBD->ulGatherEnable = BD_GATHER_ENABLE;
    
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcModulusN);
	pGatherDesc->ulInputLen = ulModulusNLen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;
	
	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcA);
	pGatherDesc->ulInputLen = ulALen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;

	return OK;
}

ULONG SSX31A_SetBDDstModNormal(PEBD_DESC * pCurBD, UCHAR* pcRes, ULONG ulResLen)
{
    pCurBD->ulOutputContext = (ULONG)virt_to_bus(pcRes);
    pCurBD->ulOutputLength0 = ulResLen;
    pCurBD->ulOutputNum  = 0;
    pCurBD->ulScatterEnable &= ~BD_SCATTER_ENABLE;
    
    return OK;
}

ULONG SSX31A_SetBDSrcModNormal(PEBD_DESC * pCurBD, UCHAR* pcModulusN, ULONG ulModulusNLen, UCHAR* pcA, ULONG ulALen, UCHAR* pcB, ULONG ulBLen)
{
	SSX31A_ICD* pGatherDesc = NULL;

    pGatherDesc = (SSX31A_ICD*)Malloc( 3 * sizeof(SSX31A_ICD) );

	
    if (pGatherDesc == NULL)
    {
#ifdef HI_DBG    
        PRINT("SSX31A driver PE send mem alloc fail\r\n");
#endif	
        return ERR;                               
    }

    pCurBD->ulInputContext  = (ULONG)virt_to_bus(pGatherDesc);  
    pCurBD->ulInputNum = 3;
    pCurBD->ulInputLength= ulModulusNLen + ulALen + ulBLen;
    pCurBD->ulGatherEnable = BD_GATHER_ENABLE;
    
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcModulusN);
	pGatherDesc->ulInputLen = ulModulusNLen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;
	

	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcA);
	pGatherDesc->ulInputLen = ulALen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;


	pGatherDesc ++;
	pGatherDesc->ulInputPtr = (ULONG)virt_to_bus(pcB);
	pGatherDesc->ulInputLen = ulBLen;
	pGatherDesc->ulInputAttrib = ICD_ATTRIB_LAST_PART;
	pGatherDesc->ulOrig = 0;



	return OK;
}


ULONG SSX31A_MOD(SSX31ADRV_CTRL* pDrvCtrl, SSX31AMOD_S* pSSX31AMod)
{
    PEBD_DESC * pCurBD = NULL;
    PERD_DESC * pCurRD = NULL;
    UCHAR* pRes = NULL;
    UCHAR* pRes1 = NULL;
    UCHAR* pResAligned = NULL;  
    UCHAR* pResAligned1 = NULL;  
    int i;
    ULONG ulTmt = 0;
    LONG lIntMask;



    if ( pDrvCtrl->ulCurrDMA2BdReadPtr == ((pDrvCtrl->ulCurrDMA2BdWritePtr + 1) & (SSX31A_DMA2_BDQUEUE_LEN - 1)))  /* 发送队列写指针加1取模 */
    {
#ifdef HI_DBG    
        PRINT("BD Queue full:BD Read:%d write %d", 
            pDrvCtrl->ulCurrDMA2BdReadPtr,
            pDrvCtrl->ulCurrDMA2BdWritePtr);
#endif	    
        return ERR;
    }

    SplImp(&lIntMask);


    pCurBD = &((PEBD_DESC *)(pDrvCtrl->ulDMA2BDMemBase))[pDrvCtrl->ulCurrDMA2BdWritePtr];

    switch ( pSSX31AMod->ucOpCode )
    {
	case BD_OPCODE_MODULE_ADD:
	case BD_OPCODE_MODULE_SUBTRACT:
	case BD_OPCODE_MODULE_MULTIPLY:
	case BD_OPCODE_MODULE_POWER:
	{     
		
		pRes = Malloc( pSSX31AMod->ulResLen + 4);
		if (pRes == NULL)
		{
#ifdef HI_DBG  		
			PRINT ("\n can't malloc!");
#endif			
			goto error;
		}
		pResAligned = four_bytes_align (pRes); 
		
		if ( SSX31A_SetBDSrcModNormal( pCurBD, pSSX31AMod->pcModulusN, pSSX31AMod->ulModulusNLen, pSSX31AMod->pcA, pSSX31AMod->ulALen,
		                                                               pSSX31AMod->pcB, pSSX31AMod->ulBLen ) == ERR )
		{
			goto error;						
		}

		if ( SSX31A_SetBDDstModNormal(pCurBD, pResAligned, pSSX31AMod->ulResLen) == ERR )
	    	{
	    		goto error;
		}
		
		break;
	}	
	
	case BD_OPCODE_MODULE_GET:   
	{ 
		pRes = Malloc( pSSX31AMod->ulResLen + 4);
		if (pRes == NULL)
		{
#ifdef HI_DBG  		
			PRINT ("\n can't malloc!");
#endif			
			goto error;
		}
		pResAligned = four_bytes_align (pRes); 
		
		if ( SSX31A_SetBDSrcModGet(pCurBD, pSSX31AMod->pcModulusN, pSSX31AMod->ulModulusNLen, pSSX31AMod->pcA, pSSX31AMod->ulALen ) == ERR )
		{
			goto error;
		}

		if ( SSX31A_SetBDDstModNormal(pCurBD, pResAligned, pSSX31AMod->ulResLen) == ERR )
	   	{
	    		goto error;
		}

		break;
	}

	case BD_OPCODE_DOUBLE_MODULE_POWER: 
	{
		pRes = Malloc( pSSX31AMod->ulResLen + 4);
		if (pRes == NULL)
		{
#ifdef HI_DBG  		
			PRINT ("\n can't malloc!");
#endif			
			goto error;
		}
		pResAligned = four_bytes_align (pRes); 
		
		pRes1 = Malloc( pSSX31AMod->ulRes1Len + 4);
		if (pRes1 == NULL)
		{
#ifdef HI_DBG  		
			PRINT ("\n can't malloc!");
#endif			
			goto error;
		}
		pResAligned1 = four_bytes_align (pRes1); 
	
		if ( SSX31A_SetBDSrcModDouble(pCurBD, pSSX31AMod->pcModulusN, pSSX31AMod->ulModulusNLen, pSSX31AMod->pcA, pSSX31AMod->ulALen,
		pSSX31AMod->pcB, pSSX31AMod->ulBLen, pSSX31AMod->pcModulusN1, pSSX31AMod->ulModulusN1Len, pSSX31AMod->pcA1, pSSX31AMod->ulA1Len,
		pSSX31AMod->pcB1, pSSX31AMod->ulB1Len ) == ERR )
		{
			goto error;
		}
		if ( SSX31A_SetBDDstModDouble(pCurBD, pResAligned, pSSX31AMod->ulResLen, pResAligned1, pSSX31AMod->ulRes1Len) == ERR )
		{
			goto error;
		}
		
		break;
		
 	}
	default:
		break;
	}
    

    pCurBD->ulOpCode = pSSX31AMod->ucOpCode;
    pCurBD->ulFlag = pSSX31AMod->ucFlg;

#if 0
{
	ULONG* pulTmp = NULL;
	ULONG* pulTmp1 = NULL;
	int i;
	
	pulTmp = (ULONG*)pCurBD;
	
	PRINT ("\r\nBD: %08x %08x %08x %08x %08x %08x ", pulTmp[0], pulTmp[1], pulTmp[2], pulTmp[3], pulTmp[4], pulTmp[5]); 
	
	pulTmp1 = (ULONG*)((ULONG)bus_to_virt ( pulTmp[1] ));
	for (i=0; i<6; i++)
	{
		PRINT ("\r\nicd %d: %08x %08x", i, pulTmp1[0], pulTmp1[1]);
		pulTmp = (ULONG*)((ULONG)bus_to_virt ( pulTmp1[0] ));
		PRINT ("\r\n buf: %08x", pulTmp[0]);
		
		pulTmp1 += 2;
	}
	
}
#endif
    


    pDrvCtrl->ulCurrDMA2BdWritePtr = (pDrvCtrl->ulCurrDMA2BdWritePtr + 1) & (SSX31A_DMA2_BDQUEUE_LEN - 1); 
    PciWrite32(SSX31A_BQWP2_RW, pDrvCtrl->ulCurrDMA2BdWritePtr);
    

    pDrvCtrl->ulFreeDMA2BDs --;

    ulTmt = (DMA2_TMOUT & 0xffff)*100 + 100000;

    for (i = 0; i < ulTmt; i ++)
    {
        UsDelay(10);


        PciRead32(SSX31A_BQRP2_RW, &pDrvCtrl->ulCurrDMA2BdReadPtr);
        

        PciRead32(SSX31A_RQWP2_RW, &pDrvCtrl->ulCurrDMA2RdWritePtr);

	
        if (pDrvCtrl->ulCurrDMA2RdWritePtr == pDrvCtrl->ulCurrDMA2RdReadPtr)
        {
            continue;
        }
        else
        {

            pCurRD = &((PERD_DESC *)(pDrvCtrl->ulDMA2RDMemBase))[pDrvCtrl->ulCurrDMA2RdReadPtr];
	
	    if ((pCurRD->ulStatus & MASK_RD_STATUS_ERRCODE) != RD_STATUS_RDVALID)
	    {
#ifdef HI_DBG  	    
	    	PRINT ("\nPKE err!");
		PRINT ("\nstatus: %04x", pCurRD->ulStatus);
#endif		
		goto error; 
	    }
  
	    
	    if (pCurRD->ulGatherEnable == BD_GATHER_ENABLE )
    	    {
    	    	if (pCurRD->ulInputContext )
            	{

           		 Free( bus_to_virt(pCurRD->ulInputContext) );
        	         pCurRD->ulInputContext = NULL;
            	}
            }
           if (pCurRD->ulScatterEnable == BD_SCATTER_ENABLE )
           {
               if (pCurRD->ulOutputContext )
               {
                   Free( bus_to_virt(pCurRD->ulOutputContext) );
                   pCurRD->ulOutputContext = NULL;
               }
           }
	   
   
	    if (pResAligned != NULL)
	{
		    memcpy (pSSX31AMod->pcRes, pResAligned, pSSX31AMod->ulResLen);
    	}
	    if (pResAligned1 != NULL)
	{
		    memcpy (pSSX31AMod->pcRes1, pResAligned1, pSSX31AMod->ulRes1Len);
    	}

	    if (pRes != NULL)
	    {
	    	Free (pRes);
	    }
	    if (pRes1 != NULL)
	    {
	    	Free (pRes1);
	    }
	    
            pDrvCtrl->ulCurrDMA2RdReadPtr = (pDrvCtrl->ulCurrDMA2RdReadPtr + 1) & (SSX31A_DMA2_RDQUEUE_LEN - 1);  



            if (pDrvCtrl->ulCurrDMA2RdWritePtr == pDrvCtrl->ulCurrDMA2RdReadPtr)
            {
               PciWrite32(SSX31A_RQRP2_RW, pDrvCtrl->ulCurrDMA2RdReadPtr); 

               pDrvCtrl->ulFreeDMA2BDs ++;

               break;
            }

        }
	

    }
    if (i >= ulTmt)
    {
#ifdef HI_DBG    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -