/**CFile**************************************************************** FileName [ivyUtil.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [And-Inverter Graph package.] Synopsis [Various procedures.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - May 11, 2006.] Revision [$Id: ivyUtil.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] ***********************************************************************/ #include "ivy.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Increments the current traversal ID of the network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ManIncrementTravId( Ivy_Man_t * p ) { if ( p->nTravIds >= (1<<30)-1 - 1000 ) Ivy_ManCleanTravId( p ); p->nTravIds++; } /**Function************************************************************* Synopsis [Sets the DFS ordering of the nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ManCleanTravId( Ivy_Man_t * p ) { Ivy_Obj_t * pObj; int i; p->nTravIds = 1; Ivy_ManForEachObj( p, pObj, i ) pObj->TravId = 0; } /**Function************************************************************* Synopsis [Computes truth table of the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ManCollectCut_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vNodes ) { if ( pNode->fMarkA ) return; pNode->fMarkA = 1; assert( Ivy_ObjIsAnd(pNode) || Ivy_ObjIsExor(pNode) ); Ivy_ManCollectCut_rec( p, Ivy_ObjFanin0(pNode), vNodes ); Ivy_ManCollectCut_rec( p, Ivy_ObjFanin1(pNode), vNodes ); Vec_IntPush( vNodes, pNode->Id ); } /**Function************************************************************* Synopsis [Computes truth table of the cut.] Description [Does not modify the array of leaves. Uses array vTruth to store temporary truth tables. The returned pointer should be used immediately.] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ManCollectCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes ) { int i, Leaf; // collect and mark the leaves Vec_IntClear( vNodes ); Vec_IntForEachEntry( vLeaves, Leaf, i ) { Vec_IntPush( vNodes, Leaf ); Ivy_ManObj(p, Leaf)->fMarkA = 1; } // collect and mark the nodes Ivy_ManCollectCut_rec( p, pRoot, vNodes ); // clean the nodes Vec_IntForEachEntry( vNodes, Leaf, i ) Ivy_ManObj(p, Leaf)->fMarkA = 0; } /**Function************************************************************* Synopsis [Returns the pointer to the truth table.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned * Ivy_ObjGetTruthStore( int ObjNum, Vec_Int_t * vTruth ) { return ((unsigned *)Vec_IntArray(vTruth)) + 8 * ObjNum; } /**Function************************************************************* Synopsis [Computes truth table of the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ManCutTruthOne( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vTruth, int nWords ) { unsigned * pTruth, * pTruth0, * pTruth1; int i; pTruth = Ivy_ObjGetTruthStore( pNode->TravId, vTruth ); pTruth0 = Ivy_ObjGetTruthStore( Ivy_ObjFanin0(pNode)->TravId, vTruth ); pTruth1 = Ivy_ObjGetTruthStore( Ivy_ObjFanin1(pNode)->TravId, vTruth ); if ( Ivy_ObjIsExor(pNode) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] ^ pTruth1[i]; else if ( !Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] & pTruth1[i]; else if ( !Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = pTruth0[i] & ~pTruth1[i]; else if ( Ivy_ObjFaninC0(pNode) && !Ivy_ObjFaninC1(pNode) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = ~pTruth0[i] & pTruth1[i]; else // if ( Ivy_ObjFaninC0(pNode) && Ivy_ObjFaninC1(pNode) ) for ( i = 0; i < nWords; i++ ) pTruth[i] = ~pTruth0[i] & ~pTruth1[i]; } /**Function************************************************************* Synopsis [Computes truth table of the cut.] Description [Does not modify the array of leaves. Uses array vTruth to store temporary truth tables. The returned pointer should be used immediately.] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned * Ivy_ManCutTruth( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth ) { static unsigned uTruths[8][8] = { // elementary truth tables { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA }, { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC }, { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 }, { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 }, { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 }, { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF }, { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } }; int i, Leaf; // collect the cut Ivy_ManCollectCut( p, pRoot, vLeaves, vNodes ); // set the node numbers Vec_IntForEachEntry( vNodes, Leaf, i ) Ivy_ManObj(p, Leaf)->TravId = i; // alloc enough memory Vec_IntClear( vTruth ); Vec_IntGrow( vTruth, 8 * Vec_IntSize(vNodes) ); // set the elementary truth tables Vec_IntForEachEntry( vLeaves, Leaf, i ) memcpy( Ivy_ObjGetTruthStore(i, vTruth), uTruths[i], 8 * sizeof(unsigned) ); // compute truths for other nodes Vec_IntForEachEntryStart( vNodes, Leaf, i, Vec_IntSize(vLeaves) ) Ivy_ManCutTruthOne( p, Ivy_ManObj(p, Leaf), vTruth, 8 ); return Ivy_ObjGetTruthStore( pRoot->TravId, vTruth ); } /**Function************************************************************* Synopsis [Collect the latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p ) { Vec_Int_t * vLatches; Ivy_Obj_t * pObj; int i; vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) ); Ivy_ManForEachLatch( p, pObj, i ) Vec_IntPush( vLatches, pObj->Id ); return vLatches; } /**Function************************************************************* Synopsis [Collect the latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ivy_ManLevels( Ivy_Man_t * p ) { Ivy_Obj_t * pObj; int i, LevelMax = 0; Ivy_ManForEachPo( p, pObj, i ) LevelMax = IVY_MAX( LevelMax, (int)Ivy_ObjFanin0(pObj)->Level ); return LevelMax; } /**Function************************************************************* Synopsis [Collect the latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ivy_ManResetLevels_rec( Ivy_Obj_t * pObj ) { if ( pObj->Level || Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) ) return pObj->Level; if ( Ivy_ObjIsBuf(pObj) ) return pObj->Level = Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); assert( Ivy_ObjIsNode(pObj) ); Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); Ivy_ManResetLevels_rec( Ivy_ObjFanin1(pObj) ); return pObj->Level = Ivy_ObjLevelNew( pObj ); } /**Function************************************************************* Synopsis [Collect the latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ManResetLevels( Ivy_Man_t * p ) { Ivy_Obj_t * pObj; int i; Ivy_ManForEachObj( p, pObj, i ) pObj->Level = 0; Ivy_ManForEachCo( p, pObj, i ) Ivy_ManResetLevels_rec( Ivy_ObjFanin0(pObj) ); } /**Function************************************************************* Synopsis [References/references the node and returns MFFC size.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ivy_ObjRefDeref( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fReference, int fLabel ) { Ivy_Obj_t * pNode0, * pNode1; int Counter; // label visited nodes if ( fLabel ) Ivy_ObjSetTravIdCurrent( p, pNode ); // skip the CI if ( Ivy_ObjIsPi(pNode) ) return 0; assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) || Ivy_ObjIsLatch(pNode) ); // process the internal node pNode0 = Ivy_ObjFanin0(pNode); pNode1 = Ivy_ObjFanin1(pNode); Counter = Ivy_ObjIsNode(pNode); if ( fReference ) { if ( pNode0->nRefs++ == 0 ) Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel ); if ( pNode1 && pNode1->nRefs++ == 0 ) Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel ); } else { assert( pNode0->nRefs > 0 ); assert( pNode1 == NULL || pNode1->nRefs > 0 ); if ( --pNode0->nRefs == 0 ) Counter += Ivy_ObjRefDeref( p, pNode0, fReference, fLabel ); if ( pNode1 && --pNode1->nRefs == 0 ) Counter += Ivy_ObjRefDeref( p, pNode1, fReference, fLabel ); } return Counter; } /**Function************************************************************* Synopsis [Labels MFFC with the current label.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ivy_ObjMffcLabel( Ivy_Man_t * p, Ivy_Obj_t * pNode ) { int nConeSize1, nConeSize2; assert( !Ivy_IsComplement( pNode ) ); assert( Ivy_ObjIsNode( pNode ) ); nConeSize1 = Ivy_ObjRefDeref( p, pNode, 0, 1 ); // dereference nConeSize2 = Ivy_ObjRefDeref( p, pNode, 1, 0 ); // reference assert( nConeSize1 == nConeSize2 ); assert( nConeSize1 > 0 ); return nConeSize1; } /**Function************************************************************* Synopsis [Recursively updates fanout levels.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ObjUpdateLevel_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { Ivy_Obj_t * pFanout; Vec_Ptr_t * vFanouts; int i, LevelNew; assert( p->fFanout ); assert( Ivy_ObjIsNode(pObj) ); vFanouts = Vec_PtrAlloc( 10 ); Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i ) { if ( Ivy_ObjIsCo(pFanout) ) { // assert( (int)Ivy_ObjFanin0(pFanout)->Level <= p->nLevelMax ); continue; } LevelNew = Ivy_ObjLevelNew( pFanout ); if ( (int)pFanout->Level == LevelNew ) continue; pFanout->Level = LevelNew; Ivy_ObjUpdateLevel_rec( p, pFanout ); } Vec_PtrFree( vFanouts ); } /**Function************************************************************* Synopsis [Compute the new required level.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ivy_ObjLevelRNew( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { Ivy_Obj_t * pFanout; Vec_Ptr_t * vFanouts; int i, Required, LevelNew = 1000000; assert( p->fFanout && p->vRequired ); vFanouts = Vec_PtrAlloc( 10 ); Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i ) { Required = Vec_IntEntry(p->vRequired, pFanout->Id); LevelNew = IVY_MIN( LevelNew, Required ); } Vec_PtrFree( vFanouts ); return LevelNew - 1; } /**Function************************************************************* Synopsis [Recursively updates fanout levels.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ObjUpdateLevelR_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int ReqNew ) { Ivy_Obj_t * pFanin; if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) ) return; assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); // process the first fanin pFanin = Ivy_ObjFanin0(pObj); if ( Vec_IntEntry(p->vRequired, pFanin->Id) > ReqNew - 1 ) { Vec_IntWriteEntry( p->vRequired, pFanin->Id, ReqNew - 1 ); Ivy_ObjUpdateLevelR_rec( p, pFanin, ReqNew - 1 ); } if ( Ivy_ObjIsBuf(pObj) ) return; // process the second fanin pFanin = Ivy_ObjFanin1(pObj); if ( Vec_IntEntry(p->vRequired, pFanin->Id) > ReqNew - 1 ) { Vec_IntWriteEntry( p->vRequired, pFanin->Id, ReqNew - 1 ); Ivy_ObjUpdateLevelR_rec( p, pFanin, ReqNew - 1 ); } } /**Function************************************************************* Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ivy_ObjIsMuxType( Ivy_Obj_t * pNode ) { Ivy_Obj_t * pNode0, * pNode1; // check that the node is regular assert( !Ivy_IsComplement(pNode) ); // if the node is not AND, this is not MUX if ( !Ivy_ObjIsAnd(pNode) ) return 0; // if the children are not complemented, this is not MUX if ( !Ivy_ObjFaninC0(pNode) || !Ivy_ObjFaninC1(pNode) ) return 0; // get children pNode0 = Ivy_ObjFanin0(pNode); pNode1 = Ivy_ObjFanin1(pNode); // if the children are not ANDs, this is not MUX if ( !Ivy_ObjIsAnd(pNode0) || !Ivy_ObjIsAnd(pNode1) ) return 0; // otherwise the node is MUX iff it has a pair of equal grandchildren return (Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC0(pNode1))) || (Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC1(pNode1))) || (Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC0(pNode1))) || (Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC1(pNode1))); } /**Function************************************************************* Synopsis [Recognizes what nodes are control and data inputs of a MUX.] Description [If the node is a MUX, returns the control variable C. Assigns nodes T and E to be the then and else variables of the MUX. Node C is never complemented. Nodes T and E can be complemented. This function also recognizes EXOR/NEXOR gates as MUXes.] SideEffects [] SeeAlso [] ***********************************************************************/ Ivy_Obj_t * Ivy_ObjRecognizeMux( Ivy_Obj_t * pNode, Ivy_Obj_t ** ppNodeT, Ivy_Obj_t ** ppNodeE ) { Ivy_Obj_t * pNode0, * pNode1; assert( !Ivy_IsComplement(pNode) ); assert( Ivy_ObjIsMuxType(pNode) ); // get children pNode0 = Ivy_ObjFanin0(pNode); pNode1 = Ivy_ObjFanin1(pNode); // find the control variable // if ( pNode1->p1 == Fraig_Not(pNode2->p1) ) if ( Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC0(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p1) ) if ( Ivy_ObjFaninC0(pNode0) ) { // pNode2->p1 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); return Ivy_ObjChild0(pNode1);//pNode2->p1; } else { // pNode1->p1 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); return Ivy_ObjChild0(pNode0);//pNode1->p1; } } // else if ( pNode1->p1 == Fraig_Not(pNode2->p2) ) else if ( Ivy_ObjFaninId0(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC0(pNode0) ^ Ivy_ObjFaninC1(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p1) ) if ( Ivy_ObjFaninC0(pNode0) ) { // pNode2->p2 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); return Ivy_ObjChild1(pNode1);//pNode2->p2; } else { // pNode1->p1 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode0));//pNode1->p2); *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); return Ivy_ObjChild0(pNode0);//pNode1->p1; } } // else if ( pNode1->p2 == Fraig_Not(pNode2->p1) ) else if ( Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId0(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC0(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p2) ) if ( Ivy_ObjFaninC1(pNode0) ) { // pNode2->p1 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); return Ivy_ObjChild0(pNode1);//pNode2->p1; } else { // pNode1->p2 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); *ppNodeE = Ivy_Not(Ivy_ObjChild1(pNode1));//pNode2->p2); return Ivy_ObjChild1(pNode0);//pNode1->p2; } } // else if ( pNode1->p2 == Fraig_Not(pNode2->p2) ) else if ( Ivy_ObjFaninId1(pNode0) == Ivy_ObjFaninId1(pNode1) && (Ivy_ObjFaninC1(pNode0) ^ Ivy_ObjFaninC1(pNode1)) ) { // if ( Fraig_IsComplement(pNode1->p2) ) if ( Ivy_ObjFaninC1(pNode0) ) { // pNode2->p2 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); return Ivy_ObjChild1(pNode1);//pNode2->p2; } else { // pNode1->p2 is positive phase of C *ppNodeT = Ivy_Not(Ivy_ObjChild0(pNode0));//pNode1->p1); *ppNodeE = Ivy_Not(Ivy_ObjChild0(pNode1));//pNode2->p1); return Ivy_ObjChild1(pNode0);//pNode1->p2; } } assert( 0 ); // this is not MUX return NULL; } /**Function************************************************************* Synopsis [Returns the real fanin.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj ) { Ivy_Obj_t * pFanin; if ( pObj == NULL || !Ivy_ObjIsBuf( Ivy_Regular(pObj) ) ) return pObj; pFanin = Ivy_ObjReal( Ivy_ObjChild0(Ivy_Regular(pObj)) ); return Ivy_NotCond( pFanin, Ivy_IsComplement(pObj) ); } /**Function************************************************************* Synopsis [Prints node in HAIG.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Ivy_ObjPrintVerbose( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fHaig ) { Ivy_Obj_t * pTemp; int fShowFanouts = 0; assert( !Ivy_IsComplement(pObj) ); printf( "Node %5d : ", Ivy_ObjId(pObj) ); if ( Ivy_ObjIsConst1(pObj) ) printf( "constant 1" ); else if ( Ivy_ObjIsPi(pObj) ) printf( "PI" ); else if ( Ivy_ObjIsPo(pObj) ) printf( "PO" ); else if ( Ivy_ObjIsLatch(pObj) ) printf( "latch (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") ); else if ( Ivy_ObjIsBuf(pObj) ) printf( "buffer (%d%s)", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " ") ); else printf( "AND( %5d%s, %5d%s )", Ivy_ObjFanin0(pObj)->Id, (Ivy_ObjFaninC0(pObj)? "\'" : " "), Ivy_ObjFanin1(pObj)->Id, (Ivy_ObjFaninC1(pObj)? "\'" : " ") ); printf( " (refs = %3d)", Ivy_ObjRefs(pObj) ); if ( fShowFanouts ) { Vec_Ptr_t * vFanouts; Ivy_Obj_t * pFanout; int i; vFanouts = Vec_PtrAlloc( 10 ); printf( "\nFanouts:\n" ); Ivy_ObjForEachFanout( p, pObj, vFanouts, pFanout, i ) { printf( " " ); printf( "Node %5d : ", Ivy_ObjId(pFanout) ); if ( Ivy_ObjIsPo(pFanout) ) printf( "PO" ); else if ( Ivy_ObjIsLatch(pFanout) ) printf( "latch (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") ); else if ( Ivy_ObjIsBuf(pFanout) ) printf( "buffer (%d%s)", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " ") ); else printf( "AND( %5d%s, %5d%s )", Ivy_ObjFanin0(pFanout)->Id, (Ivy_ObjFaninC0(pFanout)? "\'" : " "), Ivy_ObjFanin1(pFanout)->Id, (Ivy_ObjFaninC1(pFanout)? "\'" : " ") ); printf( "\n" ); } Vec_PtrFree( vFanouts ); return; } if ( !fHaig ) { if ( pObj->pEquiv == NULL ) printf( " HAIG node not given" ); else printf( " HAIG node = %d%s", Ivy_Regular(pObj->pEquiv)->Id, (Ivy_IsComplement(pObj->pEquiv)? "\'" : " ") ); return; } if ( pObj->pEquiv == NULL ) return; // there are choices if ( Ivy_ObjRefs(pObj) > 0 ) { // print equivalence class printf( " { %5d ", pObj->Id ); assert( !Ivy_IsComplement(pObj->pEquiv) ); for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) ) printf( " %5d%s", pTemp->Id, (Ivy_IsComplement(pTemp->pEquiv)? "\'" : " ") ); printf( " }" ); return; } // this is a secondary node for ( pTemp = Ivy_Regular(pObj->pEquiv); Ivy_ObjRefs(pTemp) == 0; pTemp = I
#
# Copyright (C) 2006-2011 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

CRYPTO_MENU:=Cryptographic API modules

CRYPTO_MODULES = \
	ALGAPI2=crypto_algapi \
	BLKCIPHER2=crypto_blkcipher

CRYPTOMGR_MODULES = \
	AEAD2=aead \
	MANAGER2=cryptomgr \

crypto_confvar=CONFIG_CRYPTO_$(word 1,$(subst =,$(space),$(1)))
crypto_file=$(LINUX_DIR)/crypto/$(word 2,$(subst =,$(space),$(1))).ko
crypto_name=$(if $(findstring y,$($(call crypto_confvar,$(1)))),,$(word 2,$(subst =,$(space),$(1))))

define KernelPackage/crypto-core
  SUBMENU:=$(CRYPTO_MENU)
  TITLE:=Core CryptoAPI modules
  KCONFIG:= \
	CONFIG_CRYPTO=y \
	CONFIG_CRYPTO_HW=y \
	CONFIG_CRYPTO_BLKCIPHER \
	CONFIG_CRYPTO_ALGAPI \
	$(foreach mod,$(CRYPTO_MODULES),$(call crypto_confvar,$(mod)))
  FILES:=$(foreach mod,$(CRYPTO_MODULES),$(call crypto_file,$(mod)))
endef

$(eval $(call KernelPackage,crypto-core))


define AddDepends/crypto
  SUBMENU:=$(CRYPTO_MENU)
  DEPENDS+=+kmod-crypto-core $(1)
endef

define KernelPackage/crypto-hash
  TITLE:=CryptoAPI hash support
  KCONFIG:=CONFIG_CRYPTO_HASH
  FILES:=$(LINUX_DIR)/crypto/crypto_hash.ko
  AUTOLOAD:=$(call AutoLoad,02,crypto_hash,1)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-hash))


define KernelPackage/crypto-manager
  TITLE:=CryptoAPI algorithm manager
  DEPENDS:=+kmod-crypto-hash +kmod-crypto-pcompress
  KCONFIG:= \
	CONFIG_CRYPTO_AEAD \
	CONFIG_CRYPTO_MANAGER \
	$(foreach mod,$(CRYPTOMGR_MODULES),$(call crypto_confvar,$(mod)))
  FILES:=$(foreach mod,$(CRYPTOMGR_MODULES),$(call crypto_file,$(mod)))
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-manager))


define KernelPackage/crypto-pcompress
  TITLE:=CryptoAPI Partial (de)compression operations
  KCONFIG:= \
	CONFIG_CRYPTO_PCOMP=y \
	CONFIG_CRYPTO_PCOMP2
  FILES:=$(LINUX_DIR)/crypto/pcompress.ko
  AUTOLOAD:=$(call AutoLoad,09,pcompress)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-pcompress))


define KernelPackage/crypto-user
  TITLE:=CryptoAPI userspace interface
  DEPENDS:=+kmod-crypto-hash +kmod-crypto-manager
  KCONFIG:= \
	CONFIG_CRYPTO_USER_API \
	CONFIG_CRYPTO_USER_API_HASH \
	CONFIG_CRYPTO_USER_API_SKCIPHER
  FILES:= \
	$(LINUX_DIR)/crypto/af_alg.ko \
	$(LINUX_DIR)/crypto/algif_hash.ko \
	$(LINUX_DIR)/crypto/algif_skcipher.ko
  AUTOLOAD:=$(call AutoLoad,09,af_alg algif_hash algif_skcipher)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-user))


define KernelPackage/crypto-wq
  TITLE:=CryptoAPI work queue handling
  KCONFIG:=CONFIG_CRYPTO_WORKQUEUE
  FILES:=$(LINUX_DIR)/crypto/crypto_wq.ko
  AUTOLOAD:=$(call AutoLoad,09,crypto_wq)
  $(call AddDepends/crypto)
endef
$(eval $(call KernelPackage,crypto-wq))

define KernelPackage/crypto-rng
  TITLE:=CryptoAPI random number generation
  KCONFIG:=CONFIG_CRYPTO_RNG2
  FILES:= \
	$(LINUX_DIR)/crypto/rng.ko \
	$(LINUX_DIR)/crypto/krng.ko
  AUTOLOAD:=$(call AutoLoad,09,rng krng)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-rng))


define KernelPackage/crypto-iv
  TITLE:=CryptoAPI initialization vectors
  DEPENDS:=+kmod-crypto-manager +kmod-crypto-rng +kmod-crypto-wq
  KCONFIG:= CONFIG_CRYPTO_BLKCIPHER2
  FILES:= \
	$(LINUX_DIR)/crypto/eseqiv.ko \
	$(LINUX_DIR)/crypto/chainiv.ko
  AUTOLOAD:=$(call AutoLoad,10,eseqiv chainiv)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-iv))


define KernelPackage/crypto-hw-talitos
  TITLE:=Freescale integrated security engine (SEC) driver
  DEPENDS:=+kmod-crypto-aes +kmod-crypto-manager +kmod-crypto-hash +kmod-random-core
  KCONFIG:= \
	CONFIG_CRYPTO_DEV_TALITOS
  FILES:= \
	$(LINUX_DIR)/drivers/crypto/talitos.ko
  AUTOLOAD:=$(call AutoLoad,09,talitos)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-hw-talitos))


define KernelPackage/crypto-hw-padlock
  TITLE:=VIA PadLock ACE with AES/SHA hw crypto module
  DEPENDS:=+kmod-crypto-aes +kmod-crypto-manager
  KCONFIG:= \
	CONFIG_CRYPTO_DEV_PADLOCK \
	CONFIG_CRYPTO_DEV_PADLOCK_AES \
	CONFIG_CRYPTO_DEV_PADLOCK_SHA
  FILES:= \
	$(LINUX_DIR)/drivers/crypto/padlock-aes.ko \
	$(LINUX_DIR)/drivers/crypto/padlock-sha.ko
  AUTOLOAD:=$(call AutoLoad,09,padlock-aes padlock-sha)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-hw-padlock))


define KernelPackage/crypto-hw-geode
  TITLE:=AMD Geode hardware crypto module
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:= \
	CONFIG_CRYPTO_DEV_GEODE
  FILES:=$(LINUX_DIR)/drivers/crypto/geode-aes.ko
  AUTOLOAD:=$(call AutoLoad,09,geode-aes)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-hw-geode))


define KernelPackage/crypto-hw-hifn-795x
  TITLE:=HIFN 795x crypto accelerator
  DEPENDS:=+kmod-random-core +kmod-crypto-manager
  KCONFIG:= \
	CONFIG_CRYPTO_DEV_HIFN_795X \
	CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
  FILES:=$(LINUX_DIR)/drivers/crypto/hifn_795x.ko
  AUTOLOAD:=$(call AutoLoad,09,hifn_795x)
  $(call AddDepends/crypto,+kmod-crypto-des)
endef

$(eval $(call KernelPackage,crypto-hw-hifn-795x))


define KernelPackage/crypto-hw-ppc4xx
  TITLE:=AMCC PPC4xx hardware crypto module
  DEPENDS:=@TARGET_ppc40x||TARGET_ppc44x
  KCONFIG:= \
	CONFIG_CRYPTO_DEV_PPC4XX
  FILES:=$(LINUX_DIR)/drivers/crypto/amcc/crypto4xx.ko
  AUTOLOAD:=$(call AutoLoad,90,crypto4xx)
  $(call AddDepends/crypto,+kmod-crypto-manager +kmod-crypto-hash)
endef

define KernelPackage/crypto-hw-ppc4xx/description
  Kernel support for the AMCC PPC4xx HW crypto engine.
endef

$(eval $(call KernelPackage,crypto-hw-ppc4xx))


define KernelPackage/crypto-hw-omap
  TITLE:=TI OMAP hardware crypto modules
  DEPENDS:=@TARGET_omap
  KCONFIG:= \
	CONFIG_CRYPTO_DEV_OMAP_AES \
	CONFIG_CRYPTO_DEV_OMAP_DES \
	CONFIG_CRYPTO_DEV_OMAP_SHAM
ifneq ($(wildcard $(LINUX_DIR)/drivers/crypto/omap-des.ko),)
  FILES:= \
	$(LINUX_DIR)/drivers/crypto/omap-aes.ko \
	$(LINUX_DIR)/drivers/crypto/omap-des.ko \
	$(LINUX_DIR)/drivers/crypto/omap-sham.ko
  AUTOLOAD:=$(call AutoLoad,90,omap-aes omap-des omap-sham)
else
  FILES:= \
	$(LINUX_DIR)/drivers/crypto/omap-aes.ko \
	$(LINUX_DIR)/drivers/crypto/omap-sham.ko
  AUTOLOAD:=$(call AutoLoad,90,omap-aes omap-sham)
endif
  $(call AddDepends/crypto,+kmod-crypto-manager +kmod-crypto-hash)
endef

define KernelPackage/crypto-hw-omap/description
  Kernel support for the TI OMAP HW crypto engine.
endef

$(eval $(call KernelPackage,crypto-hw-omap))


define KernelPackage/crypto-aes
  TITLE:=AES cipher CryptoAPI module
  KCONFIG:=CONFIG_CRYPTO_AES CONFIG_CRYPTO_AES_586
  FILES:=$(LINUX_DIR)/crypto/aes_generic.ko
  AUTOLOAD:=$(call AutoLoad,09,aes_generic)
  $(call AddDepends/crypto)
endef

define KernelPackage/crypto-aes/x86
  FILES+=$(LINUX_DIR)/arch/x86/crypto/aes-i586.ko
  AUTOLOAD:=$(call AutoLoad,09,aes-i586)
endef

$(eval $(call KernelPackage,crypto-aes))


define KernelPackage/crypto-arc4
  TITLE:=ARC4 (RC4) cipher CryptoAPI module
  KCONFIG:=CONFIG_CRYPTO_ARC4
  FILES:=$(LINUX_DIR)/crypto/arc4.ko
  AUTOLOAD:=$(call AutoLoad,09,arc4)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-arc4))


define KernelPackage/crypto-authenc
  TITLE:=Combined mode wrapper for IPsec
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:=CONFIG_CRYPTO_AUTHENC
  FILES:=$(LINUX_DIR)/crypto/authenc.ko
  AUTOLOAD:=$(call AutoLoad,09,authenc)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-authenc))

define KernelPackage/crypto-cbc
  TITLE:=Cipher Block Chaining CryptoAPI module
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:=CONFIG_CRYPTO_CBC
  FILES:=$(LINUX_DIR)/crypto/cbc.ko
  AUTOLOAD:=$(call AutoLoad,09,cbc)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-cbc))

define KernelPackage/crypto-pcbc
  TITLE:=Propagating Cipher Block Chaining CryptoAPI module
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:=CONFIG_CRYPTO_PCBC
  FILES:=$(LINUX_DIR)/crypto/pcbc.ko
  AUTOLOAD:=$(call AutoLoad,09,pcbc)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-pcbc))

define KernelPackage/crypto-crc32c
  TITLE:=CRC32c CRC module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_CRC32C
  FILES:=$(LINUX_DIR)/crypto/crc32c.ko
  AUTOLOAD:=$(call AutoLoad,04,crc32c,1)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-crc32c))


define KernelPackage/crypto-des
  TITLE:=DES/3DES cipher CryptoAPI module
  KCONFIG:=CONFIG_CRYPTO_DES
  FILES:=$(LINUX_DIR)/crypto/des_generic.ko
  AUTOLOAD:=$(call AutoLoad,09,des_generic)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-des))


define KernelPackage/crypto-deflate
  TITLE:=Deflate compression CryptoAPI module
  DEPENDS:=+kmod-lib-zlib
  KCONFIG:=CONFIG_CRYPTO_DEFLATE
  FILES:=$(LINUX_DIR)/crypto/deflate.ko
  AUTOLOAD:=$(call AutoLoad,09,deflate)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-deflate))


define KernelPackage/crypto-fcrypt
  TITLE:=FCRYPT cipher CryptoAPI module
  KCONFIG:=CONFIG_CRYPTO_FCRYPT
  FILES:=$(LINUX_DIR)/crypto/fcrypt.ko
  AUTOLOAD:=$(call AutoLoad,09,fcrypt)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-fcrypt))

define KernelPackage/crypto-ecb
  TITLE:=Electronic CodeBook CryptoAPI module
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:=CONFIG_CRYPTO_ECB
  FILES:=$(LINUX_DIR)/crypto/ecb.ko
  AUTOLOAD:=$(call AutoLoad,09,ecb)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-ecb))


define KernelPackage/crypto-hmac
  TITLE:=HMAC digest CryptoAPI module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_HMAC
  FILES:=$(LINUX_DIR)/crypto/hmac.ko
  DEPENDS:=+kmod-crypto-manager
  AUTOLOAD:=$(call AutoLoad,09,hmac)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-hmac))


define KernelPackage/crypto-md4
  TITLE:=MD4 digest CryptoAPI module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_MD4
  FILES:=$(LINUX_DIR)/crypto/md4.ko
  AUTOLOAD:=$(call AutoLoad,09,md4)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-md4))


define KernelPackage/crypto-md5
  TITLE:=MD5 digest CryptoAPI module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_MD5
  FILES:=$(LINUX_DIR)/crypto/md5.ko
  AUTOLOAD:=$(call AutoLoad,09,md5)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-md5))


define KernelPackage/crypto-michael-mic
  TITLE:=Michael MIC keyed digest CryptoAPI module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_MICHAEL_MIC
  FILES:=$(LINUX_DIR)/crypto/michael_mic.ko
  AUTOLOAD:=$(call AutoLoad,09,michael_mic)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-michael-mic))


define KernelPackage/crypto-sha1
  TITLE:=SHA1 digest CryptoAPI module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_SHA1
  FILES:=$(LINUX_DIR)/crypto/sha1_generic.ko
  AUTOLOAD:=$(call AutoLoad,09,sha1_generic)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-sha1))


define KernelPackage/crypto-sha256
  TITLE:=SHA224 SHA256 digest CryptoAPI module
  DEPENDS:=+kmod-crypto-hash
  KCONFIG:=CONFIG_CRYPTO_SHA256
  FILES:=$(LINUX_DIR)/crypto/sha256_generic.ko
  AUTOLOAD:=$(call AutoLoad,09,sha256_generic)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-sha256))


ifeq ($(strip $(call CompareKernelPatchVer,$(KERNEL_PATCHVER),ge,3.6.0)),1)
camellia_mod_suffix=_generic
endif
ifeq ($(strip $(call CompareKernelPatchVer,$(KERNEL_PATCHVER),ge,3.7.0)),1)
cast56_mod_suffix=_generic
endif

define KernelPackage/crypto-misc
  TITLE:=Other CryptoAPI modules
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:= \
	CONFIG_CRYPTO_ANUBIS \
	CONFIG_CRYPTO_BLOWFISH \
	CONFIG_CRYPTO_CAMELLIA \
	CONFIG_CRYPTO_CAST5 \
	CONFIG_CRYPTO_CAST6 \
	CONFIG_CRYPTO_FCRYPT \
	CONFIG_CRYPTO_KHAZAD \
	CONFIG_CRYPTO_SERPENT \
	CONFIG_CRYPTO_SHA512 \
	CONFIG_CRYPTO_TEA \
	CONFIG_CRYPTO_TGR192 \
	CONFIG_CRYPTO_TWOFISH \
	CONFIG_CRYPTO_TWOFISH_COMMON \
	CONFIG_CRYPTO_TWOFISH_586 \
	CONFIG_CRYPTO_WP512
  FILES:= \
	$(LINUX_DIR)/crypto/anubis.ko \
	$(LINUX_DIR)/crypto/camellia$(camellia_mod_suffix).ko \
	$(if $(call kernel_patchver_ge,3.7),$(LINUX_DIR)/crypto/cast_common.ko) \
	$(LINUX_DIR)/crypto/cast5$(cast56_mod_suffix).ko \
	$(LINUX_DIR)/crypto/cast6$(cast56_mod_suffix).ko \
	$(LINUX_DIR)/crypto/khazad.ko \
	$(LINUX_DIR)/crypto/sha512_generic.ko \
	$(LINUX_DIR)/crypto/tea.ko \
	$(LINUX_DIR)/crypto/tgr192.ko \
	$(LINUX_DIR)/crypto/twofish_common.ko \
	$(LINUX_DIR)/crypto/wp512.ko \
	$(LINUX_DIR)/crypto/twofish_generic.ko \
	$(LINUX_DIR)/crypto/blowfish_common.ko \
	$(LINUX_DIR)/crypto/blowfish_generic.ko \
	$(LINUX_DIR)/crypto/serpent_generic.ko
  $(call AddDepends/crypto)
endef

define KernelPackage/crypto-misc/x86
  FILES+=$(LINUX_DIR)/arch/x86/crypto/twofish-i586.ko
endef

$(eval $(call KernelPackage,crypto-misc))


define KernelPackage/crypto-ocf
  TITLE:=OCF modules
  DEPENDS:=+@OPENSSL_ENGINE_CRYPTO @!TARGET_uml +kmod-crypto-manager
  KCONFIG:= \
	CONFIG_OCF_OCF \
	CONFIG_OCF_CRYPTODEV \
	CONFIG_OCF_CRYPTOSOFT \
	CONFIG_OCF_FIPS=y \
	CONFIG_OCF_RANDOMHARVEST=y
  FILES:= \
	$(LINUX_DIR)/crypto/ocf/ocf.ko \
	$(LINUX_DIR)/crypto/ocf/cryptodev.ko \
	$(LINUX_DIR)/crypto/ocf/cryptosoft.ko
  AUTOLOAD:=$(call AutoLoad,09, \
	ocf \
	cryptodev \
	cryptosoft \
  )
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-ocf))


define KernelPackage/crypto-ocf-hifn7751
  TITLE:=OCF support for Hifn 6500/7751/7811/795x, Invertex AEON and NetSec 7751 devices
  DEPENDS:=+@OPENSSL_ENGINE_CRYPTO @PCI_SUPPORT @!TARGET_uml kmod-crypto-ocf
  KCONFIG:=CONFIG_OCF_HIFN
  FILES:=$(LINUX_DIR)/crypto/ocf/hifn/hifn7751.ko
  AUTOLOAD:=$(call AutoLoad,10,hifn7751)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-ocf-hifn7751))


define KernelPackage/crypto-ocf-hifnhipp
  TITLE:=OCF support for Hifn 7855/8155 devices
  DEPENDS:=+@OPENSSL_ENGINE_CRYPTO @PCI_SUPPORT @!TARGET_uml kmod-crypto-ocf
  KCONFIG:=CONFIG_OCF_HIFNHIPP
  FILES:=$(LINUX_DIR)/crypto/ocf/hifn/hifnHIPP.ko
  AUTOLOAD:=$(call AutoLoad,10,hifnHIPP)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-ocf-hifnhipp))


define KernelPackage/crypto-null
  TITLE:=Null CryptoAPI module
  KCONFIG:=CONFIG_CRYPTO_NULL
  FILES:=$(LINUX_DIR)/crypto/crypto_null.ko
  AUTOLOAD:=$(call AutoLoad,09,crypto_null)
  $(call AddDepends/crypto,+kmod-crypto-manager)
endef

$(eval $(call KernelPackage,crypto-null))


define KernelPackage/crypto-test
  TITLE:=Test CryptoAPI module
  KCONFIG:=CONFIG_CRYPTO_TEST
  FILES:=$(LINUX_DIR)/crypto/tcrypt.ko
  $(call AddDepends/crypto,+kmod-crypto-manager)
endef

$(eval $(call KernelPackage,crypto-test))


define KernelPackage/crypto-xts
  TITLE:=XTS cipher CryptoAPI module
  DEPENDS:=+kmod-crypto-manager
  KCONFIG:= \
	CONFIG_CRYPTO_GF128MUL \
	CONFIG_CRYPTO_XTS
  FILES:= \
	$(LINUX_DIR)/crypto/xts.ko \
	$(LINUX_DIR)/crypto/gf128mul.ko
  AUTOLOAD:=$(call AutoLoad,09, \
	gf128mul \
	xts \
  )
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-xts))


define KernelPackage/crypto-mv-cesa
  TITLE:=Marvell crypto engine
  DEPENDS:=+kmod-crypto-manager +kmod-crypto-aes @TARGET_kirkwood||TARGET_orion||TARGET_mvebu
  KCONFIG:=CONFIG_CRYPTO_DEV_MV_CESA
  FILES:=$(LINUX_DIR)/drivers/crypto/mv_cesa.ko
  AUTOLOAD:=$(call AutoLoad,09,mv_cesa)
  $(call AddDepends/crypto)
endef

$(eval $(call KernelPackage,crypto-mv-cesa))