ocf.patch 722 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653
  1. diff -Nur linux-2.6.29.1.orig/crypto/Kconfig linux-2.6.29.1/crypto/Kconfig
  2. --- linux-2.6.29.1.orig/crypto/Kconfig 2009-04-02 22:55:27.000000000 +0200
  3. +++ linux-2.6.29.1/crypto/Kconfig 2009-04-20 20:01:21.396548617 +0200
  4. @@ -737,3 +737,5 @@
  5. source "drivers/crypto/Kconfig"
  6. endif # if CRYPTO
  7. +
  8. +source "crypto/ocf/Kconfig"
  9. diff -Nur linux-2.6.29.1.orig/crypto/Makefile linux-2.6.29.1/crypto/Makefile
  10. --- linux-2.6.29.1.orig/crypto/Makefile 2009-04-02 22:55:27.000000000 +0200
  11. +++ linux-2.6.29.1/crypto/Makefile 2009-04-20 20:01:21.396548617 +0200
  12. @@ -79,6 +79,8 @@
  13. obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
  14. obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
  15. +obj-$(CONFIG_OCF_OCF) += ocf/
  16. +
  17. #
  18. # generic algorithms and the async_tx api
  19. #
  20. diff -Nur linux-2.6.29.1.orig/crypto/ocf/Config.in linux-2.6.29.1/crypto/ocf/Config.in
  21. --- linux-2.6.29.1.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
  22. +++ linux-2.6.29.1/crypto/ocf/Config.in 2009-04-20 20:01:21.400550244 +0200
  23. @@ -0,0 +1,34 @@
  24. +#############################################################################
  25. +
  26. +mainmenu_option next_comment
  27. +comment 'OCF Configuration'
  28. +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
  29. +dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
  30. + CONFIG_OCF_FIPS $CONFIG_OCF_OCF
  31. +dep_mbool ' enable harvesting entropy for /dev/random' \
  32. + CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
  33. +dep_tristate ' cryptodev (user space support)' \
  34. + CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
  35. +dep_tristate ' cryptosoft (software crypto engine)' \
  36. + CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
  37. +dep_tristate ' safenet (HW crypto engine)' \
  38. + CONFIG_OCF_SAFE $CONFIG_OCF_OCF
  39. +dep_tristate ' IXP4xx (HW crypto engine)' \
  40. + CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
  41. +dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
  42. + CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
  43. +dep_tristate ' hifn (HW crypto engine)' \
  44. + CONFIG_OCF_HIFN $CONFIG_OCF_OCF
  45. +dep_tristate ' talitos (HW crypto engine)' \
  46. + CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
  47. +dep_tristate ' pasemi (HW crypto engine)' \
  48. + CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
  49. +dep_tristate ' ep80579 (HW crypto engine)' \
  50. + CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
  51. +dep_tristate ' ocfnull (does no crypto)' \
  52. + CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
  53. +dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
  54. + CONFIG_OCF_BENCH $CONFIG_OCF_OCF
  55. +endmenu
  56. +
  57. +#############################################################################
  58. diff -Nur linux-2.6.29.1.orig/crypto/ocf/Kconfig linux-2.6.29.1/crypto/ocf/Kconfig
  59. --- linux-2.6.29.1.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
  60. +++ linux-2.6.29.1/crypto/ocf/Kconfig 2009-04-20 20:01:21.548558198 +0200
  61. @@ -0,0 +1,101 @@
  62. +menu "OCF Configuration"
  63. +
  64. +config OCF_OCF
  65. + tristate "OCF (Open Cryptograhic Framework)"
  66. + help
  67. + A linux port of the OpenBSD/FreeBSD crypto framework.
  68. +
  69. +config OCF_RANDOMHARVEST
  70. + bool "crypto random --- harvest entropy for /dev/random"
  71. + depends on OCF_OCF
  72. + help
  73. + Includes code to harvest random numbers from devices that support it.
  74. +
  75. +config OCF_FIPS
  76. + bool "enable fips RNG checks"
  77. + depends on OCF_OCF && OCF_RANDOMHARVEST
  78. + help
  79. + Run all RNG provided data through a fips check before
  80. + adding it /dev/random's entropy pool.
  81. +
  82. +config OCF_CRYPTODEV
  83. + tristate "cryptodev (user space support)"
  84. + depends on OCF_OCF
  85. + help
  86. + The user space API to access crypto hardware.
  87. +
  88. +config OCF_CRYPTOSOFT
  89. + tristate "cryptosoft (software crypto engine)"
  90. + depends on OCF_OCF
  91. + help
  92. + A software driver for the OCF framework that uses
  93. + the kernel CryptoAPI.
  94. +
  95. +config OCF_SAFE
  96. + tristate "safenet (HW crypto engine)"
  97. + depends on OCF_OCF
  98. + help
  99. + A driver for a number of the safenet Excel crypto accelerators.
  100. + Currently tested and working on the 1141 and 1741.
  101. +
  102. +config OCF_IXP4XX
  103. + tristate "IXP4xx (HW crypto engine)"
  104. + depends on OCF_OCF
  105. + help
  106. + XScale IXP4xx crypto accelerator driver. Requires the
  107. + Intel Access library.
  108. +
  109. +config OCF_IXP4XX_SHA1_MD5
  110. + bool "IXP4xx SHA1 and MD5 Hashing"
  111. + depends on OCF_IXP4XX
  112. + help
  113. + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
  114. + Note: this is MUCH slower than using cryptosoft (software crypto engine).
  115. +
  116. +config OCF_HIFN
  117. + tristate "hifn (HW crypto engine)"
  118. + depends on OCF_OCF
  119. + help
  120. + OCF driver for various HIFN based crypto accelerators.
  121. + (7951, 7955, 7956, 7751, 7811)
  122. +
  123. +config OCF_HIFNHIPP
  124. + tristate "Hifn HIPP (HW packet crypto engine)"
  125. + depends on OCF_OCF
  126. + help
  127. + OCF driver for various HIFN (HIPP) based crypto accelerators
  128. + (7855)
  129. +
  130. +config OCF_TALITOS
  131. + tristate "talitos (HW crypto engine)"
  132. + depends on OCF_OCF
  133. + help
  134. + OCF driver for Freescale's security engine (SEC/talitos).
  135. +
  136. +config OCF_PASEMI
  137. + tristate "pasemi (HW crypto engine)"
  138. + depends on OCF_OCF && PPC_PASEMI
  139. + help
  140. + OCF driver for the PA Semi PWRficient DMA Engine
  141. +
  142. +config OCF_EP80579
  143. + tristate "ep80579 (HW crypto engine)"
  144. + depends on OCF_OCF
  145. + help
  146. + OCF driver for the Intel EP80579 Integrated Processor Product Line.
  147. +
  148. +config OCF_OCFNULL
  149. + tristate "ocfnull (fake crypto engine)"
  150. + depends on OCF_OCF
  151. + help
  152. + OCF driver for measuring ipsec overheads (does no crypto)
  153. +
  154. +config OCF_BENCH
  155. + tristate "ocf-bench (HW crypto in-kernel benchmark)"
  156. + depends on OCF_OCF
  157. + help
  158. + A very simple encryption test for the in-kernel interface
  159. + of OCF. Also includes code to benchmark the IXP Access library
  160. + for comparison.
  161. +
  162. +endmenu
  163. diff -Nur linux-2.6.29.1.orig/crypto/ocf/Makefile linux-2.6.29.1/crypto/ocf/Makefile
  164. --- linux-2.6.29.1.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
  165. +++ linux-2.6.29.1/crypto/ocf/Makefile 2009-04-20 20:01:21.548558198 +0200
  166. @@ -0,0 +1,121 @@
  167. +# for SGlinux builds
  168. +-include $(ROOTDIR)/modules/.config
  169. +
  170. +OCF_OBJS = crypto.o criov.o
  171. +
  172. +ifdef CONFIG_OCF_RANDOMHARVEST
  173. + OCF_OBJS += random.o
  174. +endif
  175. +
  176. +ifdef CONFIG_OCF_FIPS
  177. + OCF_OBJS += rndtest.o
  178. +endif
  179. +
  180. +# Add in autoconf.h to get #defines for CONFIG_xxx
  181. +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
  182. +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
  183. + EXTRA_CFLAGS += -include $(AUTOCONF_H)
  184. + export EXTRA_CFLAGS
  185. +endif
  186. +
  187. +ifndef obj
  188. + obj ?= .
  189. + _obj = subdir
  190. + mod-subdirs := safe hifn ixp4xx talitos ocfnull
  191. + export-objs += crypto.o criov.o random.o
  192. + list-multi += ocf.o
  193. + _slash :=
  194. +else
  195. + _obj = obj
  196. + _slash := /
  197. +endif
  198. +
  199. +EXTRA_CFLAGS += -I$(obj)/.
  200. +
  201. +obj-$(CONFIG_OCF_OCF) += ocf.o
  202. +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
  203. +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
  204. +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
  205. +
  206. +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
  207. +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
  208. +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
  209. +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
  210. +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
  211. +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
  212. +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
  213. +
  214. +ocf-objs := $(OCF_OBJS)
  215. +
  216. +$(list-multi) dummy1: $(ocf-objs)
  217. + $(LD) -r -o $@ $(ocf-objs)
  218. +
  219. +.PHONY:
  220. +clean:
  221. + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
  222. + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
  223. +
  224. +ifdef TOPDIR
  225. +-include $(TOPDIR)/Rules.make
  226. +endif
  227. +
  228. +#
  229. +# release gen targets
  230. +#
  231. +
  232. +.PHONY: patch
  233. +patch:
  234. + REL=`date +%Y%m%d`; \
  235. + patch=ocf-linux-$$REL.patch; \
  236. + patch24=ocf-linux-24-$$REL.patch; \
  237. + patch26=ocf-linux-26-$$REL.patch; \
  238. + ( \
  239. + find . -name Makefile; \
  240. + find . -name Config.in; \
  241. + find . -name Kconfig; \
  242. + find . -name README; \
  243. + find . -name '*.[ch]' | grep -v '.mod.c'; \
  244. + ) | while read t; do \
  245. + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
  246. + done > $$patch; \
  247. + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
  248. + cat patches/linux-2.6.26-ocf.patch $$patch > $$patch26
  249. +
  250. +.PHONY: tarball
  251. +tarball:
  252. + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
  253. + CURDIR=`pwd`; \
  254. + rm -rf /tmp/ocf-linux-$$REL*; \
  255. + mkdir -p $$RELDIR/tools; \
  256. + cp README* $$RELDIR; \
  257. + cp patches/openss*.patch $$RELDIR; \
  258. + cp patches/crypto-tools.patch $$RELDIR; \
  259. + cp tools/[!C]* $$RELDIR/tools; \
  260. + cd ..; \
  261. + tar cvf $$RELDIR/ocf-linux.tar \
  262. + --exclude=CVS \
  263. + --exclude=.* \
  264. + --exclude=*.o \
  265. + --exclude=*.ko \
  266. + --exclude=*.mod.* \
  267. + --exclude=README* \
  268. + --exclude=ocf-*.patch \
  269. + --exclude=ocf/patches/openss*.patch \
  270. + --exclude=ocf/patches/crypto-tools.patch \
  271. + --exclude=ocf/tools \
  272. + ocf; \
  273. + gzip -9 $$RELDIR/ocf-linux.tar; \
  274. + cd /tmp; \
  275. + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
  276. + gzip -9 ocf-linux-$$REL.tar; \
  277. + cd $$CURDIR/../../user; \
  278. + rm -rf /tmp/crypto-tools-$$REL*; \
  279. + tar cvf /tmp/crypto-tools-$$REL.tar \
  280. + --exclude=CVS \
  281. + --exclude=.* \
  282. + --exclude=*.o \
  283. + --exclude=cryptotest \
  284. + --exclude=cryptokeytest \
  285. + crypto-tools; \
  286. + gzip -9 /tmp/crypto-tools-$$REL.tar
  287. +
  288. diff -Nur linux-2.6.29.1.orig/crypto/ocf/README linux-2.6.29.1/crypto/ocf/README
  289. --- linux-2.6.29.1.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
  290. +++ linux-2.6.29.1/crypto/ocf/README 2009-04-20 20:01:21.584560546 +0200
  291. @@ -0,0 +1,167 @@
  292. +README - ocf-linux-20071215
  293. +---------------------------
  294. +
  295. +This README provides instructions for getting ocf-linux compiled and
  296. +operating in a generic linux environment. For other information you
  297. +might like to visit the home page for this project:
  298. +
  299. + http://ocf-linux.sourceforge.net/
  300. +
  301. +Adding OCF to linux
  302. +-------------------
  303. +
  304. + Not much in this file for now, just some notes. I usually build
  305. + the ocf support as modules but it can be built into the kernel as
  306. + well. To use it:
  307. +
  308. + * mknod /dev/crypto c 10 70
  309. +
  310. + * to add OCF to your kernel source, you have two options. Apply
  311. + the kernel specific patch:
  312. +
  313. + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
  314. + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
  315. +
  316. + if you do one of the above, then you can proceed to the next step,
  317. + or you can do the above process by hand with using the patches against
  318. + linux-2.4.35 and 2.6.23 to include the ocf code under crypto/ocf.
  319. + Here's how to add it:
  320. +
  321. + for 2.4.35 (and later)
  322. +
  323. + cd linux-2.4.35/crypto
  324. + tar xvzf ocf-linux.tar.gz
  325. + cd ..
  326. + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
  327. +
  328. + for 2.6.23 (and later), find the kernel patch specific (or nearest)
  329. + to your kernel versions and then:
  330. +
  331. + cd linux-2.6.NN/crypto
  332. + tar xvzf ocf-linux.tar.gz
  333. + cd ..
  334. + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
  335. +
  336. + It should be easy to take this patch and apply it to other more
  337. + recent versions of the kernels. The same patches should also work
  338. + relatively easily on kernels as old as 2.6.11 and 2.4.18.
  339. +
  340. + * under 2.4 if you are on a non-x86 platform, you may need to:
  341. +
  342. + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
  343. +
  344. + so that you can build the kernel crypto support needed for the cryptosoft
  345. + driver.
  346. +
  347. + * For simplicity you should enable all the crypto support in your kernel
  348. + except for the test driver. Likewise for the OCF options. Do not
  349. + enable OCF crypto drivers for HW that you do not have (for example
  350. + ixp4xx will not compile on non-Xscale systems).
  351. +
  352. + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
  353. + crypto/cryptodev.h in an include directory that is used for building
  354. + applications for your platform. For example on a host system that
  355. + might be:
  356. +
  357. + /usr/include/crypto/cryptodev.h
  358. +
  359. + * patch your openssl-0.9.8i code with the openssl-0.9.8i.patch.
  360. + (NOTE: there is no longer a need to patch ssh). The patch is against:
  361. + openssl-0_9_8e
  362. +
  363. + If you need a patch for an older version of openssl, you should look
  364. + to older OCF releases. This patch is unlikely to work on older
  365. + openssl versions.
  366. +
  367. + openssl-0.9.8i.patch
  368. + - enables --with-cryptodev for non BSD systems
  369. + - adds -cpu option to openssl speed for calculating CPU load
  370. + under linux
  371. + - fixes null pointer in openssl speed multi thread output.
  372. + - fixes test keys to work with linux crypto's more stringent
  373. + key checking.
  374. + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
  375. + with the --with-cryptodev-digests option
  376. + - fixes bug in engine code caching.
  377. +
  378. + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
  379. + tools for testing OCF (ie., cryptotest).
  380. +
  381. +How to load the OCF drivers
  382. +---------------------------
  383. +
  384. + First insert the base modules:
  385. +
  386. + insmod ocf
  387. + insmod cryptodev
  388. +
  389. + You can then install the software OCF driver with:
  390. +
  391. + insmod cryptosoft
  392. +
  393. + and one or more of the OCF HW drivers with:
  394. +
  395. + insmod safe
  396. + insmod hifn7751
  397. + insmod ixp4xx
  398. + ...
  399. +
  400. + all the drivers take a debug option to enable verbose debug so that
  401. + you can see what is going on. For debug you load them as:
  402. +
  403. + insmod ocf crypto_debug=1
  404. + insmod cryptodev cryptodev_debug=1
  405. + insmod cryptosoft swcr_debug=1
  406. +
  407. + You may load more than one OCF crypto driver but then there is no guarantee
  408. + as to which will be used.
  409. +
  410. + You can also enable debug at run time on 2.6 systems with the following:
  411. +
  412. + echo 1 > /sys/module/ocf/parameters/crypto_debug
  413. + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
  414. + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
  415. + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
  416. + echo 1 > /sys/module/safe/parameters/safe_debug
  417. + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
  418. + ...
  419. +
  420. +Testing the OCF support
  421. +-----------------------
  422. +
  423. + run "cryptotest", it should do a short test for a couple of
  424. + des packets. If it does everything is working.
  425. +
  426. + If this works, then ssh will use the driver when invoked as:
  427. +
  428. + ssh -c 3des username@host
  429. +
  430. + to see for sure that it is operating, enable debug as defined above.
  431. +
  432. + To get a better idea of performance run:
  433. +
  434. + cryptotest 100 4096
  435. +
  436. + There are more options to cryptotest, see the help.
  437. +
  438. + It is also possible to use openssl to test the speed of the crypto
  439. + drivers.
  440. +
  441. + openssl speed -evp des -engine cryptodev -elapsed
  442. + openssl speed -evp des3 -engine cryptodev -elapsed
  443. + openssl speed -evp aes128 -engine cryptodev -elapsed
  444. +
  445. + and multiple threads (10) with:
  446. +
  447. + openssl speed -evp des -engine cryptodev -elapsed -multi 10
  448. + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
  449. + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
  450. +
  451. + for public key testing you can try:
  452. +
  453. + cryptokeytest
  454. + openssl speed -engine cryptodev rsa -elapsed
  455. + openssl speed -engine cryptodev dsa -elapsed
  456. +
  457. +David McCullough
  458. +david_mccullough@securecomputing.com
  459. diff -Nur linux-2.6.29.1.orig/crypto/ocf/criov.c linux-2.6.29.1/crypto/ocf/criov.c
  460. --- linux-2.6.29.1.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
  461. +++ linux-2.6.29.1/crypto/ocf/criov.c 2009-04-20 20:01:21.400550244 +0200
  462. @@ -0,0 +1,215 @@
  463. +/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
  464. +
  465. +/*
  466. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  467. + * Copyright (C) 2006-2007 David McCullough
  468. + * Copyright (C) 2004-2005 Intel Corporation.
  469. + * The license and original author are listed below.
  470. + *
  471. + * Copyright (c) 1999 Theo de Raadt
  472. + *
  473. + * Redistribution and use in source and binary forms, with or without
  474. + * modification, are permitted provided that the following conditions
  475. + * are met:
  476. + *
  477. + * 1. Redistributions of source code must retain the above copyright
  478. + * notice, this list of conditions and the following disclaimer.
  479. + * 2. Redistributions in binary form must reproduce the above copyright
  480. + * notice, this list of conditions and the following disclaimer in the
  481. + * documentation and/or other materials provided with the distribution.
  482. + * 3. The name of the author may not be used to endorse or promote products
  483. + * derived from this software without specific prior written permission.
  484. + *
  485. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  486. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  487. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  488. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  489. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  490. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  491. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  492. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  493. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  494. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  495. + *
  496. +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
  497. + */
  498. +
  499. +#ifndef AUTOCONF_INCLUDED
  500. +#include <linux/config.h>
  501. +#endif
  502. +#include <linux/module.h>
  503. +#include <linux/init.h>
  504. +#include <linux/slab.h>
  505. +#include <linux/uio.h>
  506. +#include <linux/skbuff.h>
  507. +#include <linux/kernel.h>
  508. +#include <linux/mm.h>
  509. +#include <asm/io.h>
  510. +
  511. +#include <uio.h>
  512. +#include <cryptodev.h>
  513. +
  514. +/*
  515. + * This macro is only for avoiding code duplication, as we need to skip
  516. + * given number of bytes in the same way in three functions below.
  517. + */
  518. +#define CUIO_SKIP() do { \
  519. + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
  520. + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
  521. + while (off > 0) { \
  522. + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
  523. + if (off < iov->iov_len) \
  524. + break; \
  525. + off -= iov->iov_len; \
  526. + iol--; \
  527. + iov++; \
  528. + } \
  529. +} while (0)
  530. +
  531. +void
  532. +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
  533. +{
  534. + struct iovec *iov = uio->uio_iov;
  535. + int iol = uio->uio_iovcnt;
  536. + unsigned count;
  537. +
  538. + CUIO_SKIP();
  539. + while (len > 0) {
  540. + KASSERT(iol >= 0, ("%s: empty", __func__));
  541. + count = min((int)(iov->iov_len - off), len);
  542. + memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
  543. + len -= count;
  544. + cp += count;
  545. + off = 0;
  546. + iol--;
  547. + iov++;
  548. + }
  549. +}
  550. +
  551. +void
  552. +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
  553. +{
  554. + struct iovec *iov = uio->uio_iov;
  555. + int iol = uio->uio_iovcnt;
  556. + unsigned count;
  557. +
  558. + CUIO_SKIP();
  559. + while (len > 0) {
  560. + KASSERT(iol >= 0, ("%s: empty", __func__));
  561. + count = min((int)(iov->iov_len - off), len);
  562. + memcpy(((caddr_t)iov->iov_base) + off, cp, count);
  563. + len -= count;
  564. + cp += count;
  565. + off = 0;
  566. + iol--;
  567. + iov++;
  568. + }
  569. +}
  570. +
  571. +/*
  572. + * Return a pointer to iov/offset of location in iovec list.
  573. + */
  574. +struct iovec *
  575. +cuio_getptr(struct uio *uio, int loc, int *off)
  576. +{
  577. + struct iovec *iov = uio->uio_iov;
  578. + int iol = uio->uio_iovcnt;
  579. +
  580. + while (loc >= 0) {
  581. + /* Normal end of search */
  582. + if (loc < iov->iov_len) {
  583. + *off = loc;
  584. + return (iov);
  585. + }
  586. +
  587. + loc -= iov->iov_len;
  588. + if (iol == 0) {
  589. + if (loc == 0) {
  590. + /* Point at the end of valid data */
  591. + *off = iov->iov_len;
  592. + return (iov);
  593. + } else
  594. + return (NULL);
  595. + } else {
  596. + iov++, iol--;
  597. + }
  598. + }
  599. +
  600. + return (NULL);
  601. +}
  602. +
  603. +EXPORT_SYMBOL(cuio_copyback);
  604. +EXPORT_SYMBOL(cuio_copydata);
  605. +EXPORT_SYMBOL(cuio_getptr);
  606. +
  607. +
  608. +static void
  609. +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
  610. +{
  611. + int i;
  612. + if (offset < skb_headlen(skb)) {
  613. + memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
  614. + len -= skb_headlen(skb);
  615. + cp += skb_headlen(skb);
  616. + }
  617. + offset -= skb_headlen(skb);
  618. + for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
  619. + if (offset < skb_shinfo(skb)->frags[i].size) {
  620. + memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
  621. + skb_shinfo(skb)->frags[i].page_offset,
  622. + cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
  623. + len -= skb_shinfo(skb)->frags[i].size;
  624. + cp += skb_shinfo(skb)->frags[i].size;
  625. + }
  626. + offset -= skb_shinfo(skb)->frags[i].size;
  627. + }
  628. +}
  629. +
  630. +void
  631. +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
  632. +{
  633. +
  634. + if ((flags & CRYPTO_F_SKBUF) != 0)
  635. + skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
  636. + else if ((flags & CRYPTO_F_IOV) != 0)
  637. + cuio_copyback((struct uio *)buf, off, size, in);
  638. + else
  639. + bcopy(in, buf + off, size);
  640. +}
  641. +
  642. +void
  643. +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
  644. +{
  645. +
  646. + if ((flags & CRYPTO_F_SKBUF) != 0)
  647. + skb_copy_bits((struct sk_buff *)buf, off, out, size);
  648. + else if ((flags & CRYPTO_F_IOV) != 0)
  649. + cuio_copydata((struct uio *)buf, off, size, out);
  650. + else
  651. + bcopy(buf + off, out, size);
  652. +}
  653. +
  654. +int
  655. +crypto_apply(int flags, caddr_t buf, int off, int len,
  656. + int (*f)(void *, void *, u_int), void *arg)
  657. +{
  658. +#if 0
  659. + int error;
  660. +
  661. + if ((flags & CRYPTO_F_SKBUF) != 0)
  662. + error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
  663. + else if ((flags & CRYPTO_F_IOV) != 0)
  664. + error = cuio_apply((struct uio *)buf, off, len, f, arg);
  665. + else
  666. + error = (*f)(arg, buf + off, len);
  667. + return (error);
  668. +#else
  669. + KASSERT(0, ("crypto_apply not implemented!\n"));
  670. +#endif
  671. + return 0;
  672. +}
  673. +
  674. +EXPORT_SYMBOL(crypto_copyback);
  675. +EXPORT_SYMBOL(crypto_copydata);
  676. +EXPORT_SYMBOL(crypto_apply);
  677. +
  678. diff -Nur linux-2.6.29.1.orig/crypto/ocf/crypto.c linux-2.6.29.1/crypto/ocf/crypto.c
  679. --- linux-2.6.29.1.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
  680. +++ linux-2.6.29.1/crypto/ocf/crypto.c 2009-04-20 20:01:21.408550425 +0200
  681. @@ -0,0 +1,1741 @@
  682. +/*-
  683. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  684. + * Copyright (C) 2006-2007 David McCullough
  685. + * Copyright (C) 2004-2005 Intel Corporation.
  686. + * The license and original author are listed below.
  687. + *
  688. + * Redistribution and use in source and binary forms, with or without
  689. + * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
  690. + *
  691. + * modification, are permitted provided that the following conditions
  692. + * are met:
  693. + * 1. Redistributions of source code must retain the above copyright
  694. + * notice, this list of conditions and the following disclaimer.
  695. + * 2. Redistributions in binary form must reproduce the above copyright
  696. + * notice, this list of conditions and the following disclaimer in the
  697. + * documentation and/or other materials provided with the distribution.
  698. + *
  699. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  700. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  701. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  702. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  703. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  704. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  705. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  706. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  707. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  708. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  709. + */
  710. +
  711. +#if 0
  712. +#include <sys/cdefs.h>
  713. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
  714. +#endif
  715. +
  716. +/*
  717. + * Cryptographic Subsystem.
  718. + *
  719. + * This code is derived from the Openbsd Cryptographic Framework (OCF)
  720. + * that has the copyright shown below. Very little of the original
  721. + * code remains.
  722. + */
  723. +/*-
  724. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  725. + *
  726. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  727. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  728. + * supported the development of this code.
  729. + *
  730. + * Copyright (c) 2000, 2001 Angelos D. Keromytis
  731. + *
  732. + * Permission to use, copy, and modify this software with or without fee
  733. + * is hereby granted, provided that this entire notice is included in
  734. + * all source code copies of any software which is or includes a copy or
  735. + * modification of this software.
  736. + *
  737. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  738. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  739. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  740. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  741. + * PURPOSE.
  742. + *
  743. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
  744. + */
  745. +
  746. +
  747. +#ifndef AUTOCONF_INCLUDED
  748. +#include <linux/config.h>
  749. +#endif
  750. +#include <linux/module.h>
  751. +#include <linux/init.h>
  752. +#include <linux/list.h>
  753. +#include <linux/slab.h>
  754. +#include <linux/wait.h>
  755. +#include <linux/sched.h>
  756. +#include <linux/spinlock.h>
  757. +#include <linux/version.h>
  758. +#include <cryptodev.h>
  759. +
  760. +/*
  761. + * keep track of whether or not we have been initialised, a big
  762. + * issue if we are linked into the kernel and a driver gets started before
  763. + * us
  764. + */
  765. +static int crypto_initted = 0;
  766. +
  767. +/*
  768. + * Crypto drivers register themselves by allocating a slot in the
  769. + * crypto_drivers table with crypto_get_driverid() and then registering
  770. + * each algorithm they support with crypto_register() and crypto_kregister().
  771. + */
  772. +
  773. +/*
  774. + * lock on driver table
  775. + * we track its state as spin_is_locked does not do anything on non-SMP boxes
  776. + */
  777. +static spinlock_t crypto_drivers_lock;
  778. +static int crypto_drivers_locked; /* for non-SMP boxes */
  779. +
  780. +#define CRYPTO_DRIVER_LOCK() \
  781. + ({ \
  782. + spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
  783. + crypto_drivers_locked = 1; \
  784. + dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
  785. + })
  786. +#define CRYPTO_DRIVER_UNLOCK() \
  787. + ({ \
  788. + dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
  789. + crypto_drivers_locked = 0; \
  790. + spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
  791. + })
  792. +#define CRYPTO_DRIVER_ASSERT() \
  793. + ({ \
  794. + if (!crypto_drivers_locked) { \
  795. + dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
  796. + } \
  797. + })
  798. +
  799. +/*
  800. + * Crypto device/driver capabilities structure.
  801. + *
  802. + * Synchronization:
  803. + * (d) - protected by CRYPTO_DRIVER_LOCK()
  804. + * (q) - protected by CRYPTO_Q_LOCK()
  805. + * Not tagged fields are read-only.
  806. + */
  807. +struct cryptocap {
  808. + device_t cc_dev; /* (d) device/driver */
  809. + u_int32_t cc_sessions; /* (d) # of sessions */
  810. + u_int32_t cc_koperations; /* (d) # os asym operations */
  811. + /*
  812. + * Largest possible operator length (in bits) for each type of
  813. + * encryption algorithm. XXX not used
  814. + */
  815. + u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
  816. + u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
  817. + u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
  818. +
  819. + int cc_flags; /* (d) flags */
  820. +#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
  821. + int cc_qblocked; /* (q) symmetric q blocked */
  822. + int cc_kqblocked; /* (q) asymmetric q blocked */
  823. +};
  824. +static struct cryptocap *crypto_drivers = NULL;
  825. +static int crypto_drivers_num = 0;
  826. +
  827. +/*
  828. + * There are two queues for crypto requests; one for symmetric (e.g.
  829. + * cipher) operations and one for asymmetric (e.g. MOD)operations.
  830. + * A single mutex is used to lock access to both queues. We could
  831. + * have one per-queue but having one simplifies handling of block/unblock
  832. + * operations.
  833. + */
  834. +static int crp_sleep = 0;
  835. +static LIST_HEAD(crp_q); /* request queues */
  836. +static LIST_HEAD(crp_kq);
  837. +
  838. +static spinlock_t crypto_q_lock;
  839. +
  840. +int crypto_all_qblocked = 0; /* protect with Q_LOCK */
  841. +module_param(crypto_all_qblocked, int, 0444);
  842. +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
  843. +
  844. +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
  845. +module_param(crypto_all_kqblocked, int, 0444);
  846. +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
  847. +
  848. +#define CRYPTO_Q_LOCK() \
  849. + ({ \
  850. + spin_lock_irqsave(&crypto_q_lock, q_flags); \
  851. + dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
  852. + })
  853. +#define CRYPTO_Q_UNLOCK() \
  854. + ({ \
  855. + dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
  856. + spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
  857. + })
  858. +
  859. +/*
  860. + * There are two queues for processing completed crypto requests; one
  861. + * for the symmetric and one for the asymmetric ops. We only need one
  862. + * but have two to avoid type futzing (cryptop vs. cryptkop). A single
  863. + * mutex is used to lock access to both queues. Note that this lock
  864. + * must be separate from the lock on request queues to insure driver
  865. + * callbacks don't generate lock order reversals.
  866. + */
  867. +static LIST_HEAD(crp_ret_q); /* callback queues */
  868. +static LIST_HEAD(crp_ret_kq);
  869. +
  870. +static spinlock_t crypto_ret_q_lock;
  871. +#define CRYPTO_RETQ_LOCK() \
  872. + ({ \
  873. + spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
  874. + dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
  875. + })
  876. +#define CRYPTO_RETQ_UNLOCK() \
  877. + ({ \
  878. + dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
  879. + spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
  880. + })
  881. +#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
  882. +
  883. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  884. +static kmem_cache_t *cryptop_zone;
  885. +static kmem_cache_t *cryptodesc_zone;
  886. +#else
  887. +static struct kmem_cache *cryptop_zone;
  888. +static struct kmem_cache *cryptodesc_zone;
  889. +#endif
  890. +
  891. +#define debug crypto_debug
  892. +int crypto_debug = 0;
  893. +module_param(crypto_debug, int, 0644);
  894. +MODULE_PARM_DESC(crypto_debug, "Enable debug");
  895. +EXPORT_SYMBOL(crypto_debug);
  896. +
  897. +/*
  898. + * Maximum number of outstanding crypto requests before we start
  899. + * failing requests. We need this to prevent DOS when too many
  900. + * requests are arriving for us to keep up. Otherwise we will
  901. + * run the system out of memory. Since crypto is slow, we are
  902. + * usually the bottleneck that needs to say, enough is enough.
  903. + *
  904. + * We cannot print errors when this condition occurs, we are already too
  905. + * slow, printing anything will just kill us
  906. + */
  907. +
  908. +static int crypto_q_cnt = 0;
  909. +module_param(crypto_q_cnt, int, 0444);
  910. +MODULE_PARM_DESC(crypto_q_cnt,
  911. + "Current number of outstanding crypto requests");
  912. +
  913. +static int crypto_q_max = 1000;
  914. +module_param(crypto_q_max, int, 0644);
  915. +MODULE_PARM_DESC(crypto_q_max,
  916. + "Maximum number of outstanding crypto requests");
  917. +
  918. +#define bootverbose crypto_verbose
  919. +static int crypto_verbose = 0;
  920. +module_param(crypto_verbose, int, 0644);
  921. +MODULE_PARM_DESC(crypto_verbose,
  922. + "Enable verbose crypto startup");
  923. +
  924. +int crypto_usercrypto = 1; /* userland may do crypto reqs */
  925. +module_param(crypto_usercrypto, int, 0644);
  926. +MODULE_PARM_DESC(crypto_usercrypto,
  927. + "Enable/disable user-mode access to crypto support");
  928. +
  929. +int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
  930. +module_param(crypto_userasymcrypto, int, 0644);
  931. +MODULE_PARM_DESC(crypto_userasymcrypto,
  932. + "Enable/disable user-mode access to asymmetric crypto support");
  933. +
  934. +int crypto_devallowsoft = 0; /* only use hardware crypto */
  935. +module_param(crypto_devallowsoft, int, 0644);
  936. +MODULE_PARM_DESC(crypto_devallowsoft,
  937. + "Enable/disable use of software crypto support");
  938. +
  939. +static pid_t cryptoproc = (pid_t) -1;
  940. +static struct completion cryptoproc_exited;
  941. +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
  942. +static pid_t cryptoretproc = (pid_t) -1;
  943. +static struct completion cryptoretproc_exited;
  944. +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
  945. +
  946. +static int crypto_proc(void *arg);
  947. +static int crypto_ret_proc(void *arg);
  948. +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
  949. +static int crypto_kinvoke(struct cryptkop *krp, int flags);
  950. +static void crypto_exit(void);
  951. +static int crypto_init(void);
  952. +
  953. +static struct cryptostats cryptostats;
  954. +
  955. +static struct cryptocap *
  956. +crypto_checkdriver(u_int32_t hid)
  957. +{
  958. + if (crypto_drivers == NULL)
  959. + return NULL;
  960. + return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
  961. +}
  962. +
  963. +/*
  964. + * Compare a driver's list of supported algorithms against another
  965. + * list; return non-zero if all algorithms are supported.
  966. + */
  967. +static int
  968. +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
  969. +{
  970. + const struct cryptoini *cr;
  971. +
  972. + /* See if all the algorithms are supported. */
  973. + for (cr = cri; cr; cr = cr->cri_next)
  974. + if (cap->cc_alg[cr->cri_alg] == 0)
  975. + return 0;
  976. + return 1;
  977. +}
  978. +
  979. +/*
  980. + * Select a driver for a new session that supports the specified
  981. + * algorithms and, optionally, is constrained according to the flags.
  982. + * The algorithm we use here is pretty stupid; just use the
  983. + * first driver that supports all the algorithms we need. If there
  984. + * are multiple drivers we choose the driver with the fewest active
  985. + * sessions. We prefer hardware-backed drivers to software ones.
  986. + *
  987. + * XXX We need more smarts here (in real life too, but that's
  988. + * XXX another story altogether).
  989. + */
  990. +static struct cryptocap *
  991. +crypto_select_driver(const struct cryptoini *cri, int flags)
  992. +{
  993. + struct cryptocap *cap, *best;
  994. + int match, hid;
  995. +
  996. + CRYPTO_DRIVER_ASSERT();
  997. +
  998. + /*
  999. + * Look first for hardware crypto devices if permitted.
  1000. + */
  1001. + if (flags & CRYPTOCAP_F_HARDWARE)
  1002. + match = CRYPTOCAP_F_HARDWARE;
  1003. + else
  1004. + match = CRYPTOCAP_F_SOFTWARE;
  1005. + best = NULL;
  1006. +again:
  1007. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1008. + cap = &crypto_drivers[hid];
  1009. + /*
  1010. + * If it's not initialized, is in the process of
  1011. + * going away, or is not appropriate (hardware
  1012. + * or software based on match), then skip.
  1013. + */
  1014. + if (cap->cc_dev == NULL ||
  1015. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  1016. + (cap->cc_flags & match) == 0)
  1017. + continue;
  1018. +
  1019. + /* verify all the algorithms are supported. */
  1020. + if (driver_suitable(cap, cri)) {
  1021. + if (best == NULL ||
  1022. + cap->cc_sessions < best->cc_sessions)
  1023. + best = cap;
  1024. + }
  1025. + }
  1026. + if (best != NULL)
  1027. + return best;
  1028. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  1029. + /* sort of an Algol 68-style for loop */
  1030. + match = CRYPTOCAP_F_SOFTWARE;
  1031. + goto again;
  1032. + }
  1033. + return best;
  1034. +}
  1035. +
  1036. +/*
  1037. + * Create a new session. The crid argument specifies a crypto
  1038. + * driver to use or constraints on a driver to select (hardware
  1039. + * only, software only, either). Whatever driver is selected
  1040. + * must be capable of the requested crypto algorithms.
  1041. + */
  1042. +int
  1043. +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
  1044. +{
  1045. + struct cryptocap *cap;
  1046. + u_int32_t hid, lid;
  1047. + int err;
  1048. + unsigned long d_flags;
  1049. +
  1050. + CRYPTO_DRIVER_LOCK();
  1051. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  1052. + /*
  1053. + * Use specified driver; verify it is capable.
  1054. + */
  1055. + cap = crypto_checkdriver(crid);
  1056. + if (cap != NULL && !driver_suitable(cap, cri))
  1057. + cap = NULL;
  1058. + } else {
  1059. + /*
  1060. + * No requested driver; select based on crid flags.
  1061. + */
  1062. + cap = crypto_select_driver(cri, crid);
  1063. + /*
  1064. + * if NULL then can't do everything in one session.
  1065. + * XXX Fix this. We need to inject a "virtual" session
  1066. + * XXX layer right about here.
  1067. + */
  1068. + }
  1069. + if (cap != NULL) {
  1070. + /* Call the driver initialization routine. */
  1071. + hid = cap - crypto_drivers;
  1072. + lid = hid; /* Pass the driver ID. */
  1073. + cap->cc_sessions++;
  1074. + CRYPTO_DRIVER_UNLOCK();
  1075. + err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
  1076. + CRYPTO_DRIVER_LOCK();
  1077. + if (err == 0) {
  1078. + (*sid) = (cap->cc_flags & 0xff000000)
  1079. + | (hid & 0x00ffffff);
  1080. + (*sid) <<= 32;
  1081. + (*sid) |= (lid & 0xffffffff);
  1082. + } else
  1083. + cap->cc_sessions--;
  1084. + } else
  1085. + err = EINVAL;
  1086. + CRYPTO_DRIVER_UNLOCK();
  1087. + return err;
  1088. +}
  1089. +
  1090. +static void
  1091. +crypto_remove(struct cryptocap *cap)
  1092. +{
  1093. + CRYPTO_DRIVER_ASSERT();
  1094. + if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
  1095. + bzero(cap, sizeof(*cap));
  1096. +}
  1097. +
  1098. +/*
  1099. + * Delete an existing session (or a reserved session on an unregistered
  1100. + * driver).
  1101. + */
  1102. +int
  1103. +crypto_freesession(u_int64_t sid)
  1104. +{
  1105. + struct cryptocap *cap;
  1106. + u_int32_t hid;
  1107. + int err = 0;
  1108. + unsigned long d_flags;
  1109. +
  1110. + dprintk("%s()\n", __FUNCTION__);
  1111. + CRYPTO_DRIVER_LOCK();
  1112. +
  1113. + if (crypto_drivers == NULL) {
  1114. + err = EINVAL;
  1115. + goto done;
  1116. + }
  1117. +
  1118. + /* Determine two IDs. */
  1119. + hid = CRYPTO_SESID2HID(sid);
  1120. +
  1121. + if (hid >= crypto_drivers_num) {
  1122. + dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
  1123. + err = ENOENT;
  1124. + goto done;
  1125. + }
  1126. + cap = &crypto_drivers[hid];
  1127. +
  1128. + if (cap->cc_dev) {
  1129. + CRYPTO_DRIVER_UNLOCK();
  1130. + /* Call the driver cleanup routine, if available, unlocked. */
  1131. + err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
  1132. + CRYPTO_DRIVER_LOCK();
  1133. + }
  1134. +
  1135. + if (cap->cc_sessions)
  1136. + cap->cc_sessions--;
  1137. +
  1138. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  1139. + crypto_remove(cap);
  1140. +
  1141. +done:
  1142. + CRYPTO_DRIVER_UNLOCK();
  1143. + return err;
  1144. +}
  1145. +
  1146. +/*
  1147. + * Return an unused driver id. Used by drivers prior to registering
  1148. + * support for the algorithms they handle.
  1149. + */
  1150. +int32_t
  1151. +crypto_get_driverid(device_t dev, int flags)
  1152. +{
  1153. + struct cryptocap *newdrv;
  1154. + int i;
  1155. + unsigned long d_flags;
  1156. +
  1157. + if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  1158. + printf("%s: no flags specified when registering driver\n",
  1159. + device_get_nameunit(dev));
  1160. + return -1;
  1161. + }
  1162. +
  1163. + CRYPTO_DRIVER_LOCK();
  1164. +
  1165. + for (i = 0; i < crypto_drivers_num; i++) {
  1166. + if (crypto_drivers[i].cc_dev == NULL &&
  1167. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
  1168. + break;
  1169. + }
  1170. + }
  1171. +
  1172. + /* Out of entries, allocate some more. */
  1173. + if (i == crypto_drivers_num) {
  1174. + /* Be careful about wrap-around. */
  1175. + if (2 * crypto_drivers_num <= crypto_drivers_num) {
  1176. + CRYPTO_DRIVER_UNLOCK();
  1177. + printk("crypto: driver count wraparound!\n");
  1178. + return -1;
  1179. + }
  1180. +
  1181. + newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
  1182. + GFP_KERNEL);
  1183. + if (newdrv == NULL) {
  1184. + CRYPTO_DRIVER_UNLOCK();
  1185. + printk("crypto: no space to expand driver table!\n");
  1186. + return -1;
  1187. + }
  1188. +
  1189. + memcpy(newdrv, crypto_drivers,
  1190. + crypto_drivers_num * sizeof(struct cryptocap));
  1191. + memset(&newdrv[crypto_drivers_num], 0,
  1192. + crypto_drivers_num * sizeof(struct cryptocap));
  1193. +
  1194. + crypto_drivers_num *= 2;
  1195. +
  1196. + kfree(crypto_drivers);
  1197. + crypto_drivers = newdrv;
  1198. + }
  1199. +
  1200. + /* NB: state is zero'd on free */
  1201. + crypto_drivers[i].cc_sessions = 1; /* Mark */
  1202. + crypto_drivers[i].cc_dev = dev;
  1203. + crypto_drivers[i].cc_flags = flags;
  1204. + if (bootverbose)
  1205. + printf("crypto: assign %s driver id %u, flags %u\n",
  1206. + device_get_nameunit(dev), i, flags);
  1207. +
  1208. + CRYPTO_DRIVER_UNLOCK();
  1209. +
  1210. + return i;
  1211. +}
  1212. +
  1213. +/*
  1214. + * Lookup a driver by name. We match against the full device
  1215. + * name and unit, and against just the name. The latter gives
  1216. + * us a simple widlcarding by device name. On success return the
  1217. + * driver/hardware identifier; otherwise return -1.
  1218. + */
  1219. +int
  1220. +crypto_find_driver(const char *match)
  1221. +{
  1222. + int i, len = strlen(match);
  1223. + unsigned long d_flags;
  1224. +
  1225. + CRYPTO_DRIVER_LOCK();
  1226. + for (i = 0; i < crypto_drivers_num; i++) {
  1227. + device_t dev = crypto_drivers[i].cc_dev;
  1228. + if (dev == NULL ||
  1229. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
  1230. + continue;
  1231. + if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
  1232. + strncmp(match, device_get_name(dev), len) == 0)
  1233. + break;
  1234. + }
  1235. + CRYPTO_DRIVER_UNLOCK();
  1236. + return i < crypto_drivers_num ? i : -1;
  1237. +}
  1238. +
  1239. +/*
  1240. + * Return the device_t for the specified driver or NULL
  1241. + * if the driver identifier is invalid.
  1242. + */
  1243. +device_t
  1244. +crypto_find_device_byhid(int hid)
  1245. +{
  1246. + struct cryptocap *cap = crypto_checkdriver(hid);
  1247. + return cap != NULL ? cap->cc_dev : NULL;
  1248. +}
  1249. +
  1250. +/*
  1251. + * Return the device/driver capabilities.
  1252. + */
  1253. +int
  1254. +crypto_getcaps(int hid)
  1255. +{
  1256. + struct cryptocap *cap = crypto_checkdriver(hid);
  1257. + return cap != NULL ? cap->cc_flags : 0;
  1258. +}
  1259. +
  1260. +/*
  1261. + * Register support for a key-related algorithm. This routine
  1262. + * is called once for each algorithm supported a driver.
  1263. + */
  1264. +int
  1265. +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
  1266. +{
  1267. + struct cryptocap *cap;
  1268. + int err;
  1269. + unsigned long d_flags;
  1270. +
  1271. + dprintk("%s()\n", __FUNCTION__);
  1272. + CRYPTO_DRIVER_LOCK();
  1273. +
  1274. + cap = crypto_checkdriver(driverid);
  1275. + if (cap != NULL &&
  1276. + (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
  1277. + /*
  1278. + * XXX Do some performance testing to determine placing.
  1279. + * XXX We probably need an auxiliary data structure that
  1280. + * XXX describes relative performances.
  1281. + */
  1282. +
  1283. + cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  1284. + if (bootverbose)
  1285. + printf("crypto: %s registers key alg %u flags %u\n"
  1286. + , device_get_nameunit(cap->cc_dev)
  1287. + , kalg
  1288. + , flags
  1289. + );
  1290. + err = 0;
  1291. + } else
  1292. + err = EINVAL;
  1293. +
  1294. + CRYPTO_DRIVER_UNLOCK();
  1295. + return err;
  1296. +}
  1297. +
  1298. +/*
  1299. + * Register support for a non-key-related algorithm. This routine
  1300. + * is called once for each such algorithm supported by a driver.
  1301. + */
  1302. +int
  1303. +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  1304. + u_int32_t flags)
  1305. +{
  1306. + struct cryptocap *cap;
  1307. + int err;
  1308. + unsigned long d_flags;
  1309. +
  1310. + dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
  1311. + driverid, alg, maxoplen, flags);
  1312. +
  1313. + CRYPTO_DRIVER_LOCK();
  1314. +
  1315. + cap = crypto_checkdriver(driverid);
  1316. + /* NB: algorithms are in the range [1..max] */
  1317. + if (cap != NULL &&
  1318. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
  1319. + /*
  1320. + * XXX Do some performance testing to determine placing.
  1321. + * XXX We probably need an auxiliary data structure that
  1322. + * XXX describes relative performances.
  1323. + */
  1324. +
  1325. + cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  1326. + cap->cc_max_op_len[alg] = maxoplen;
  1327. + if (bootverbose)
  1328. + printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
  1329. + , device_get_nameunit(cap->cc_dev)
  1330. + , alg
  1331. + , flags
  1332. + , maxoplen
  1333. + );
  1334. + cap->cc_sessions = 0; /* Unmark */
  1335. + err = 0;
  1336. + } else
  1337. + err = EINVAL;
  1338. +
  1339. + CRYPTO_DRIVER_UNLOCK();
  1340. + return err;
  1341. +}
  1342. +
  1343. +static void
  1344. +driver_finis(struct cryptocap *cap)
  1345. +{
  1346. + u_int32_t ses, kops;
  1347. +
  1348. + CRYPTO_DRIVER_ASSERT();
  1349. +
  1350. + ses = cap->cc_sessions;
  1351. + kops = cap->cc_koperations;
  1352. + bzero(cap, sizeof(*cap));
  1353. + if (ses != 0 || kops != 0) {
  1354. + /*
  1355. + * If there are pending sessions,
  1356. + * just mark as invalid.
  1357. + */
  1358. + cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  1359. + cap->cc_sessions = ses;
  1360. + cap->cc_koperations = kops;
  1361. + }
  1362. +}
  1363. +
  1364. +/*
  1365. + * Unregister a crypto driver. If there are pending sessions using it,
  1366. + * leave enough information around so that subsequent calls using those
  1367. + * sessions will correctly detect the driver has been unregistered and
  1368. + * reroute requests.
  1369. + */
  1370. +int
  1371. +crypto_unregister(u_int32_t driverid, int alg)
  1372. +{
  1373. + struct cryptocap *cap;
  1374. + int i, err;
  1375. + unsigned long d_flags;
  1376. +
  1377. + dprintk("%s()\n", __FUNCTION__);
  1378. + CRYPTO_DRIVER_LOCK();
  1379. +
  1380. + cap = crypto_checkdriver(driverid);
  1381. + if (cap != NULL &&
  1382. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
  1383. + cap->cc_alg[alg] != 0) {
  1384. + cap->cc_alg[alg] = 0;
  1385. + cap->cc_max_op_len[alg] = 0;
  1386. +
  1387. + /* Was this the last algorithm ? */
  1388. + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
  1389. + if (cap->cc_alg[i] != 0)
  1390. + break;
  1391. +
  1392. + if (i == CRYPTO_ALGORITHM_MAX + 1)
  1393. + driver_finis(cap);
  1394. + err = 0;
  1395. + } else
  1396. + err = EINVAL;
  1397. + CRYPTO_DRIVER_UNLOCK();
  1398. + return err;
  1399. +}
  1400. +
  1401. +/*
  1402. + * Unregister all algorithms associated with a crypto driver.
  1403. + * If there are pending sessions using it, leave enough information
  1404. + * around so that subsequent calls using those sessions will
  1405. + * correctly detect the driver has been unregistered and reroute
  1406. + * requests.
  1407. + */
  1408. +int
  1409. +crypto_unregister_all(u_int32_t driverid)
  1410. +{
  1411. + struct cryptocap *cap;
  1412. + int err;
  1413. + unsigned long d_flags;
  1414. +
  1415. + dprintk("%s()\n", __FUNCTION__);
  1416. + CRYPTO_DRIVER_LOCK();
  1417. + cap = crypto_checkdriver(driverid);
  1418. + if (cap != NULL) {
  1419. + driver_finis(cap);
  1420. + err = 0;
  1421. + } else
  1422. + err = EINVAL;
  1423. + CRYPTO_DRIVER_UNLOCK();
  1424. +
  1425. + return err;
  1426. +}
  1427. +
  1428. +/*
  1429. + * Clear blockage on a driver. The what parameter indicates whether
  1430. + * the driver is now ready for cryptop's and/or cryptokop's.
  1431. + */
  1432. +int
  1433. +crypto_unblock(u_int32_t driverid, int what)
  1434. +{
  1435. + struct cryptocap *cap;
  1436. + int err;
  1437. + unsigned long q_flags;
  1438. +
  1439. + CRYPTO_Q_LOCK();
  1440. + cap = crypto_checkdriver(driverid);
  1441. + if (cap != NULL) {
  1442. + if (what & CRYPTO_SYMQ) {
  1443. + cap->cc_qblocked = 0;
  1444. + crypto_all_qblocked = 0;
  1445. + }
  1446. + if (what & CRYPTO_ASYMQ) {
  1447. + cap->cc_kqblocked = 0;
  1448. + crypto_all_kqblocked = 0;
  1449. + }
  1450. + if (crp_sleep)
  1451. + wake_up_interruptible(&cryptoproc_wait);
  1452. + err = 0;
  1453. + } else
  1454. + err = EINVAL;
  1455. + CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
  1456. +
  1457. + return err;
  1458. +}
  1459. +
  1460. +/*
  1461. + * Add a crypto request to a queue, to be processed by the kernel thread.
  1462. + */
  1463. +int
  1464. +crypto_dispatch(struct cryptop *crp)
  1465. +{
  1466. + struct cryptocap *cap;
  1467. + int result = -1;
  1468. + unsigned long q_flags;
  1469. +
  1470. + dprintk("%s()\n", __FUNCTION__);
  1471. +
  1472. + cryptostats.cs_ops++;
  1473. +
  1474. + CRYPTO_Q_LOCK();
  1475. + if (crypto_q_cnt >= crypto_q_max) {
  1476. + CRYPTO_Q_UNLOCK();
  1477. + cryptostats.cs_drops++;
  1478. + return ENOMEM;
  1479. + }
  1480. + crypto_q_cnt++;
  1481. +
  1482. + /*
  1483. + * Caller marked the request to be processed immediately; dispatch
  1484. + * it directly to the driver unless the driver is currently blocked.
  1485. + */
  1486. + if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
  1487. + int hid = CRYPTO_SESID2HID(crp->crp_sid);
  1488. + cap = crypto_checkdriver(hid);
  1489. + /* Driver cannot disappear when there is an active session. */
  1490. + KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
  1491. + if (!cap->cc_qblocked) {
  1492. + crypto_all_qblocked = 0;
  1493. + crypto_drivers[hid].cc_qblocked = 1;
  1494. + CRYPTO_Q_UNLOCK();
  1495. + result = crypto_invoke(cap, crp, 0);
  1496. + CRYPTO_Q_LOCK();
  1497. + if (result != ERESTART)
  1498. + crypto_drivers[hid].cc_qblocked = 0;
  1499. + }
  1500. + }
  1501. + if (result == ERESTART) {
  1502. + /*
  1503. + * The driver ran out of resources, mark the
  1504. + * driver ``blocked'' for cryptop's and put
  1505. + * the request back in the queue. It would
  1506. + * best to put the request back where we got
  1507. + * it but that's hard so for now we put it
  1508. + * at the front. This should be ok; putting
  1509. + * it at the end does not work.
  1510. + */
  1511. + list_add(&crp->crp_next, &crp_q);
  1512. + cryptostats.cs_blocks++;
  1513. + } else if (result == -1) {
  1514. + TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  1515. + }
  1516. + if (crp_sleep)
  1517. + wake_up_interruptible(&cryptoproc_wait);
  1518. + CRYPTO_Q_UNLOCK();
  1519. + return 0;
  1520. +}
  1521. +
  1522. +/*
  1523. + * Add an asymetric crypto request to a queue,
  1524. + * to be processed by the kernel thread.
  1525. + */
  1526. +int
  1527. +crypto_kdispatch(struct cryptkop *krp)
  1528. +{
  1529. + int error;
  1530. + unsigned long q_flags;
  1531. +
  1532. + cryptostats.cs_kops++;
  1533. +
  1534. + error = crypto_kinvoke(krp, krp->krp_crid);
  1535. + if (error == ERESTART) {
  1536. + CRYPTO_Q_LOCK();
  1537. + TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  1538. + if (crp_sleep)
  1539. + wake_up_interruptible(&cryptoproc_wait);
  1540. + CRYPTO_Q_UNLOCK();
  1541. + error = 0;
  1542. + }
  1543. + return error;
  1544. +}
  1545. +
  1546. +/*
  1547. + * Verify a driver is suitable for the specified operation.
  1548. + */
  1549. +static __inline int
  1550. +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
  1551. +{
  1552. + return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
  1553. +}
  1554. +
  1555. +/*
  1556. + * Select a driver for an asym operation. The driver must
  1557. + * support the necessary algorithm. The caller can constrain
  1558. + * which device is selected with the flags parameter. The
  1559. + * algorithm we use here is pretty stupid; just use the first
  1560. + * driver that supports the algorithms we need. If there are
  1561. + * multiple suitable drivers we choose the driver with the
  1562. + * fewest active operations. We prefer hardware-backed
  1563. + * drivers to software ones when either may be used.
  1564. + */
  1565. +static struct cryptocap *
  1566. +crypto_select_kdriver(const struct cryptkop *krp, int flags)
  1567. +{
  1568. + struct cryptocap *cap, *best, *blocked;
  1569. + int match, hid;
  1570. +
  1571. + CRYPTO_DRIVER_ASSERT();
  1572. +
  1573. + /*
  1574. + * Look first for hardware crypto devices if permitted.
  1575. + */
  1576. + if (flags & CRYPTOCAP_F_HARDWARE)
  1577. + match = CRYPTOCAP_F_HARDWARE;
  1578. + else
  1579. + match = CRYPTOCAP_F_SOFTWARE;
  1580. + best = NULL;
  1581. + blocked = NULL;
  1582. +again:
  1583. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1584. + cap = &crypto_drivers[hid];
  1585. + /*
  1586. + * If it's not initialized, is in the process of
  1587. + * going away, or is not appropriate (hardware
  1588. + * or software based on match), then skip.
  1589. + */
  1590. + if (cap->cc_dev == NULL ||
  1591. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  1592. + (cap->cc_flags & match) == 0)
  1593. + continue;
  1594. +
  1595. + /* verify all the algorithms are supported. */
  1596. + if (kdriver_suitable(cap, krp)) {
  1597. + if (best == NULL ||
  1598. + cap->cc_koperations < best->cc_koperations)
  1599. + best = cap;
  1600. + }
  1601. + }
  1602. + if (best != NULL)
  1603. + return best;
  1604. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  1605. + /* sort of an Algol 68-style for loop */
  1606. + match = CRYPTOCAP_F_SOFTWARE;
  1607. + goto again;
  1608. + }
  1609. + return best;
  1610. +}
  1611. +
  1612. +/*
  1613. + * Dispatch an assymetric crypto request.
  1614. + */
  1615. +static int
  1616. +crypto_kinvoke(struct cryptkop *krp, int crid)
  1617. +{
  1618. + struct cryptocap *cap = NULL;
  1619. + int error;
  1620. + unsigned long d_flags;
  1621. +
  1622. + KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
  1623. + KASSERT(krp->krp_callback != NULL,
  1624. + ("%s: krp->crp_callback == NULL", __func__));
  1625. +
  1626. + CRYPTO_DRIVER_LOCK();
  1627. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  1628. + cap = crypto_checkdriver(crid);
  1629. + if (cap != NULL) {
  1630. + /*
  1631. + * Driver present, it must support the necessary
  1632. + * algorithm and, if s/w drivers are excluded,
  1633. + * it must be registered as hardware-backed.
  1634. + */
  1635. + if (!kdriver_suitable(cap, krp) ||
  1636. + (!crypto_devallowsoft &&
  1637. + (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
  1638. + cap = NULL;
  1639. + }
  1640. + } else {
  1641. + /*
  1642. + * No requested driver; select based on crid flags.
  1643. + */
  1644. + if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
  1645. + crid &= ~CRYPTOCAP_F_SOFTWARE;
  1646. + cap = crypto_select_kdriver(krp, crid);
  1647. + }
  1648. + if (cap != NULL && !cap->cc_kqblocked) {
  1649. + krp->krp_hid = cap - crypto_drivers;
  1650. + cap->cc_koperations++;
  1651. + CRYPTO_DRIVER_UNLOCK();
  1652. + error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
  1653. + CRYPTO_DRIVER_LOCK();
  1654. + if (error == ERESTART) {
  1655. + cap->cc_koperations--;
  1656. + CRYPTO_DRIVER_UNLOCK();
  1657. + return (error);
  1658. + }
  1659. + /* return the actual device used */
  1660. + krp->krp_crid = krp->krp_hid;
  1661. + } else {
  1662. + /*
  1663. + * NB: cap is !NULL if device is blocked; in
  1664. + * that case return ERESTART so the operation
  1665. + * is resubmitted if possible.
  1666. + */
  1667. + error = (cap == NULL) ? ENODEV : ERESTART;
  1668. + }
  1669. + CRYPTO_DRIVER_UNLOCK();
  1670. +
  1671. + if (error) {
  1672. + krp->krp_status = error;
  1673. + crypto_kdone(krp);
  1674. + }
  1675. + return 0;
  1676. +}
  1677. +
  1678. +
  1679. +/*
  1680. + * Dispatch a crypto request to the appropriate crypto devices.
  1681. + */
  1682. +static int
  1683. +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
  1684. +{
  1685. + KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
  1686. + KASSERT(crp->crp_callback != NULL,
  1687. + ("%s: crp->crp_callback == NULL", __func__));
  1688. + KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
  1689. +
  1690. + dprintk("%s()\n", __FUNCTION__);
  1691. +
  1692. +#ifdef CRYPTO_TIMING
  1693. + if (crypto_timing)
  1694. + crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
  1695. +#endif
  1696. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
  1697. + struct cryptodesc *crd;
  1698. + u_int64_t nid;
  1699. +
  1700. + /*
  1701. + * Driver has unregistered; migrate the session and return
  1702. + * an error to the caller so they'll resubmit the op.
  1703. + *
  1704. + * XXX: What if there are more already queued requests for this
  1705. + * session?
  1706. + */
  1707. + crypto_freesession(crp->crp_sid);
  1708. +
  1709. + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
  1710. + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
  1711. +
  1712. + /* XXX propagate flags from initial session? */
  1713. + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
  1714. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
  1715. + crp->crp_sid = nid;
  1716. +
  1717. + crp->crp_etype = EAGAIN;
  1718. + crypto_done(crp);
  1719. + return 0;
  1720. + } else {
  1721. + /*
  1722. + * Invoke the driver to process the request.
  1723. + */
  1724. + return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
  1725. + }
  1726. +}
  1727. +
  1728. +/*
  1729. + * Release a set of crypto descriptors.
  1730. + */
  1731. +void
  1732. +crypto_freereq(struct cryptop *crp)
  1733. +{
  1734. + struct cryptodesc *crd;
  1735. +
  1736. + if (crp == NULL)
  1737. + return;
  1738. +
  1739. +#ifdef DIAGNOSTIC
  1740. + {
  1741. + struct cryptop *crp2;
  1742. + unsigned long q_flags;
  1743. +
  1744. + CRYPTO_Q_LOCK();
  1745. + TAILQ_FOREACH(crp2, &crp_q, crp_next) {
  1746. + KASSERT(crp2 != crp,
  1747. + ("Freeing cryptop from the crypto queue (%p).",
  1748. + crp));
  1749. + }
  1750. + CRYPTO_Q_UNLOCK();
  1751. + CRYPTO_RETQ_LOCK();
  1752. + TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
  1753. + KASSERT(crp2 != crp,
  1754. + ("Freeing cryptop from the return queue (%p).",
  1755. + crp));
  1756. + }
  1757. + CRYPTO_RETQ_UNLOCK();
  1758. + }
  1759. +#endif
  1760. +
  1761. + while ((crd = crp->crp_desc) != NULL) {
  1762. + crp->crp_desc = crd->crd_next;
  1763. + kmem_cache_free(cryptodesc_zone, crd);
  1764. + }
  1765. + kmem_cache_free(cryptop_zone, crp);
  1766. +}
  1767. +
  1768. +/*
  1769. + * Acquire a set of crypto descriptors.
  1770. + */
  1771. +struct cryptop *
  1772. +crypto_getreq(int num)
  1773. +{
  1774. + struct cryptodesc *crd;
  1775. + struct cryptop *crp;
  1776. +
  1777. + crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
  1778. + if (crp != NULL) {
  1779. + memset(crp, 0, sizeof(*crp));
  1780. + INIT_LIST_HEAD(&crp->crp_next);
  1781. + init_waitqueue_head(&crp->crp_waitq);
  1782. + while (num--) {
  1783. + crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
  1784. + if (crd == NULL) {
  1785. + crypto_freereq(crp);
  1786. + return NULL;
  1787. + }
  1788. + memset(crd, 0, sizeof(*crd));
  1789. + crd->crd_next = crp->crp_desc;
  1790. + crp->crp_desc = crd;
  1791. + }
  1792. + }
  1793. + return crp;
  1794. +}
  1795. +
  1796. +/*
  1797. + * Invoke the callback on behalf of the driver.
  1798. + */
  1799. +void
  1800. +crypto_done(struct cryptop *crp)
  1801. +{
  1802. + unsigned long q_flags;
  1803. +
  1804. + dprintk("%s()\n", __FUNCTION__);
  1805. + if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
  1806. + crp->crp_flags |= CRYPTO_F_DONE;
  1807. + CRYPTO_Q_LOCK();
  1808. + crypto_q_cnt--;
  1809. + CRYPTO_Q_UNLOCK();
  1810. + } else
  1811. + printk("crypto: crypto_done op already done, flags 0x%x",
  1812. + crp->crp_flags);
  1813. + if (crp->crp_etype != 0)
  1814. + cryptostats.cs_errs++;
  1815. + /*
  1816. + * CBIMM means unconditionally do the callback immediately;
  1817. + * CBIFSYNC means do the callback immediately only if the
  1818. + * operation was done synchronously. Both are used to avoid
  1819. + * doing extraneous context switches; the latter is mostly
  1820. + * used with the software crypto driver.
  1821. + */
  1822. + if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
  1823. + ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
  1824. + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
  1825. + /*
  1826. + * Do the callback directly. This is ok when the
  1827. + * callback routine does very little (e.g. the
  1828. + * /dev/crypto callback method just does a wakeup).
  1829. + */
  1830. + crp->crp_callback(crp);
  1831. + } else {
  1832. + unsigned long r_flags;
  1833. + /*
  1834. + * Normal case; queue the callback for the thread.
  1835. + */
  1836. + CRYPTO_RETQ_LOCK();
  1837. + if (CRYPTO_RETQ_EMPTY())
  1838. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  1839. + TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
  1840. + CRYPTO_RETQ_UNLOCK();
  1841. + }
  1842. +}
  1843. +
  1844. +/*
  1845. + * Invoke the callback on behalf of the driver.
  1846. + */
  1847. +void
  1848. +crypto_kdone(struct cryptkop *krp)
  1849. +{
  1850. + struct cryptocap *cap;
  1851. + unsigned long d_flags;
  1852. +
  1853. + if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
  1854. + printk("crypto: crypto_kdone op already done, flags 0x%x",
  1855. + krp->krp_flags);
  1856. + krp->krp_flags |= CRYPTO_KF_DONE;
  1857. + if (krp->krp_status != 0)
  1858. + cryptostats.cs_kerrs++;
  1859. +
  1860. + CRYPTO_DRIVER_LOCK();
  1861. + /* XXX: What if driver is loaded in the meantime? */
  1862. + if (krp->krp_hid < crypto_drivers_num) {
  1863. + cap = &crypto_drivers[krp->krp_hid];
  1864. + cap->cc_koperations--;
  1865. + KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
  1866. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  1867. + crypto_remove(cap);
  1868. + }
  1869. + CRYPTO_DRIVER_UNLOCK();
  1870. +
  1871. + /*
  1872. + * CBIMM means unconditionally do the callback immediately;
  1873. + * This is used to avoid doing extraneous context switches
  1874. + */
  1875. + if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
  1876. + /*
  1877. + * Do the callback directly. This is ok when the
  1878. + * callback routine does very little (e.g. the
  1879. + * /dev/crypto callback method just does a wakeup).
  1880. + */
  1881. + krp->krp_callback(krp);
  1882. + } else {
  1883. + unsigned long r_flags;
  1884. + /*
  1885. + * Normal case; queue the callback for the thread.
  1886. + */
  1887. + CRYPTO_RETQ_LOCK();
  1888. + if (CRYPTO_RETQ_EMPTY())
  1889. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  1890. + TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
  1891. + CRYPTO_RETQ_UNLOCK();
  1892. + }
  1893. +}
  1894. +
  1895. +int
  1896. +crypto_getfeat(int *featp)
  1897. +{
  1898. + int hid, kalg, feat = 0;
  1899. + unsigned long d_flags;
  1900. +
  1901. + CRYPTO_DRIVER_LOCK();
  1902. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  1903. + const struct cryptocap *cap = &crypto_drivers[hid];
  1904. +
  1905. + if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
  1906. + !crypto_devallowsoft) {
  1907. + continue;
  1908. + }
  1909. + for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
  1910. + if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
  1911. + feat |= 1 << kalg;
  1912. + }
  1913. + CRYPTO_DRIVER_UNLOCK();
  1914. + *featp = feat;
  1915. + return (0);
  1916. +}
  1917. +
  1918. +/*
  1919. + * Crypto thread, dispatches crypto requests.
  1920. + */
  1921. +static int
  1922. +crypto_proc(void *arg)
  1923. +{
  1924. + struct cryptop *crp, *submit;
  1925. + struct cryptkop *krp, *krpp;
  1926. + struct cryptocap *cap;
  1927. + u_int32_t hid;
  1928. + int result, hint;
  1929. + unsigned long q_flags;
  1930. +
  1931. + ocf_daemonize("crypto");
  1932. +
  1933. + CRYPTO_Q_LOCK();
  1934. + for (;;) {
  1935. + /*
  1936. + * we need to make sure we don't get into a busy loop with nothing
  1937. + * to do, the two crypto_all_*blocked vars help us find out when
  1938. + * we are all full and can do nothing on any driver or Q. If so we
  1939. + * wait for an unblock.
  1940. + */
  1941. + crypto_all_qblocked = !list_empty(&crp_q);
  1942. +
  1943. + /*
  1944. + * Find the first element in the queue that can be
  1945. + * processed and look-ahead to see if multiple ops
  1946. + * are ready for the same driver.
  1947. + */
  1948. + submit = NULL;
  1949. + hint = 0;
  1950. + list_for_each_entry(crp, &crp_q, crp_next) {
  1951. + hid = CRYPTO_SESID2HID(crp->crp_sid);
  1952. + cap = crypto_checkdriver(hid);
  1953. + /*
  1954. + * Driver cannot disappear when there is an active
  1955. + * session.
  1956. + */
  1957. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  1958. + __func__, __LINE__));
  1959. + if (cap == NULL || cap->cc_dev == NULL) {
  1960. + /* Op needs to be migrated, process it. */
  1961. + if (submit == NULL)
  1962. + submit = crp;
  1963. + break;
  1964. + }
  1965. + if (!cap->cc_qblocked) {
  1966. + if (submit != NULL) {
  1967. + /*
  1968. + * We stop on finding another op,
  1969. + * regardless whether its for the same
  1970. + * driver or not. We could keep
  1971. + * searching the queue but it might be
  1972. + * better to just use a per-driver
  1973. + * queue instead.
  1974. + */
  1975. + if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
  1976. + hint = CRYPTO_HINT_MORE;
  1977. + break;
  1978. + } else {
  1979. + submit = crp;
  1980. + if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
  1981. + break;
  1982. + /* keep scanning for more are q'd */
  1983. + }
  1984. + }
  1985. + }
  1986. + if (submit != NULL) {
  1987. + hid = CRYPTO_SESID2HID(submit->crp_sid);
  1988. + crypto_all_qblocked = 0;
  1989. + list_del(&submit->crp_next);
  1990. + crypto_drivers[hid].cc_qblocked = 1;
  1991. + cap = crypto_checkdriver(hid);
  1992. + CRYPTO_Q_UNLOCK();
  1993. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  1994. + __func__, __LINE__));
  1995. + result = crypto_invoke(cap, submit, hint);
  1996. + CRYPTO_Q_LOCK();
  1997. + if (result == ERESTART) {
  1998. + /*
  1999. + * The driver ran out of resources, mark the
  2000. + * driver ``blocked'' for cryptop's and put
  2001. + * the request back in the queue. It would
  2002. + * best to put the request back where we got
  2003. + * it but that's hard so for now we put it
  2004. + * at the front. This should be ok; putting
  2005. + * it at the end does not work.
  2006. + */
  2007. + /* XXX validate sid again? */
  2008. + list_add(&submit->crp_next, &crp_q);
  2009. + cryptostats.cs_blocks++;
  2010. + } else
  2011. + crypto_drivers[hid].cc_qblocked=0;
  2012. + }
  2013. +
  2014. + crypto_all_kqblocked = !list_empty(&crp_kq);
  2015. +
  2016. + /* As above, but for key ops */
  2017. + krp = NULL;
  2018. + list_for_each_entry(krpp, &crp_kq, krp_next) {
  2019. + cap = crypto_checkdriver(krpp->krp_hid);
  2020. + if (cap == NULL || cap->cc_dev == NULL) {
  2021. + /*
  2022. + * Operation needs to be migrated, invalidate
  2023. + * the assigned device so it will reselect a
  2024. + * new one below. Propagate the original
  2025. + * crid selection flags if supplied.
  2026. + */
  2027. + krp->krp_hid = krp->krp_crid &
  2028. + (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
  2029. + if (krp->krp_hid == 0)
  2030. + krp->krp_hid =
  2031. + CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
  2032. + break;
  2033. + }
  2034. + if (!cap->cc_kqblocked) {
  2035. + krp = krpp;
  2036. + break;
  2037. + }
  2038. + }
  2039. + if (krp != NULL) {
  2040. + crypto_all_kqblocked = 0;
  2041. + list_del(&krp->krp_next);
  2042. + crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
  2043. + CRYPTO_Q_UNLOCK();
  2044. + result = crypto_kinvoke(krp, krp->krp_hid);
  2045. + CRYPTO_Q_LOCK();
  2046. + if (result == ERESTART) {
  2047. + /*
  2048. + * The driver ran out of resources, mark the
  2049. + * driver ``blocked'' for cryptkop's and put
  2050. + * the request back in the queue. It would
  2051. + * best to put the request back where we got
  2052. + * it but that's hard so for now we put it
  2053. + * at the front. This should be ok; putting
  2054. + * it at the end does not work.
  2055. + */
  2056. + /* XXX validate sid again? */
  2057. + list_add(&krp->krp_next, &crp_kq);
  2058. + cryptostats.cs_kblocks++;
  2059. + } else
  2060. + crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
  2061. + }
  2062. +
  2063. + if (submit == NULL && krp == NULL) {
  2064. + /*
  2065. + * Nothing more to be processed. Sleep until we're
  2066. + * woken because there are more ops to process.
  2067. + * This happens either by submission or by a driver
  2068. + * becoming unblocked and notifying us through
  2069. + * crypto_unblock. Note that when we wakeup we
  2070. + * start processing each queue again from the
  2071. + * front. It's not clear that it's important to
  2072. + * preserve this ordering since ops may finish
  2073. + * out of order if dispatched to different devices
  2074. + * and some become blocked while others do not.
  2075. + */
  2076. + dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
  2077. + __FUNCTION__,
  2078. + list_empty(&crp_q), crypto_all_qblocked,
  2079. + list_empty(&crp_kq), crypto_all_kqblocked);
  2080. + CRYPTO_Q_UNLOCK();
  2081. + crp_sleep = 1;
  2082. + wait_event_interruptible(cryptoproc_wait,
  2083. + !(list_empty(&crp_q) || crypto_all_qblocked) ||
  2084. + !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
  2085. + cryptoproc == (pid_t) -1);
  2086. + crp_sleep = 0;
  2087. + if (signal_pending (current)) {
  2088. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2089. + spin_lock_irq(&current->sigmask_lock);
  2090. +#endif
  2091. + flush_signals(current);
  2092. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2093. + spin_unlock_irq(&current->sigmask_lock);
  2094. +#endif
  2095. + }
  2096. + CRYPTO_Q_LOCK();
  2097. + dprintk("%s - awake\n", __FUNCTION__);
  2098. + if (cryptoproc == (pid_t) -1)
  2099. + break;
  2100. + cryptostats.cs_intrs++;
  2101. + }
  2102. + }
  2103. + CRYPTO_Q_UNLOCK();
  2104. + complete_and_exit(&cryptoproc_exited, 0);
  2105. +}
  2106. +
  2107. +/*
  2108. + * Crypto returns thread, does callbacks for processed crypto requests.
  2109. + * Callbacks are done here, rather than in the crypto drivers, because
  2110. + * callbacks typically are expensive and would slow interrupt handling.
  2111. + */
  2112. +static int
  2113. +crypto_ret_proc(void *arg)
  2114. +{
  2115. + struct cryptop *crpt;
  2116. + struct cryptkop *krpt;
  2117. + unsigned long r_flags;
  2118. +
  2119. + ocf_daemonize("crypto_ret");
  2120. +
  2121. + CRYPTO_RETQ_LOCK();
  2122. + for (;;) {
  2123. + /* Harvest return q's for completed ops */
  2124. + crpt = NULL;
  2125. + if (!list_empty(&crp_ret_q))
  2126. + crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
  2127. + if (crpt != NULL)
  2128. + list_del(&crpt->crp_next);
  2129. +
  2130. + krpt = NULL;
  2131. + if (!list_empty(&crp_ret_kq))
  2132. + krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
  2133. + if (krpt != NULL)
  2134. + list_del(&krpt->krp_next);
  2135. +
  2136. + if (crpt != NULL || krpt != NULL) {
  2137. + CRYPTO_RETQ_UNLOCK();
  2138. + /*
  2139. + * Run callbacks unlocked.
  2140. + */
  2141. + if (crpt != NULL)
  2142. + crpt->crp_callback(crpt);
  2143. + if (krpt != NULL)
  2144. + krpt->krp_callback(krpt);
  2145. + CRYPTO_RETQ_LOCK();
  2146. + } else {
  2147. + /*
  2148. + * Nothing more to be processed. Sleep until we're
  2149. + * woken because there are more returns to process.
  2150. + */
  2151. + dprintk("%s - sleeping\n", __FUNCTION__);
  2152. + CRYPTO_RETQ_UNLOCK();
  2153. + wait_event_interruptible(cryptoretproc_wait,
  2154. + cryptoretproc == (pid_t) -1 ||
  2155. + !list_empty(&crp_ret_q) ||
  2156. + !list_empty(&crp_ret_kq));
  2157. + if (signal_pending (current)) {
  2158. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2159. + spin_lock_irq(&current->sigmask_lock);
  2160. +#endif
  2161. + flush_signals(current);
  2162. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  2163. + spin_unlock_irq(&current->sigmask_lock);
  2164. +#endif
  2165. + }
  2166. + CRYPTO_RETQ_LOCK();
  2167. + dprintk("%s - awake\n", __FUNCTION__);
  2168. + if (cryptoretproc == (pid_t) -1) {
  2169. + dprintk("%s - EXITING!\n", __FUNCTION__);
  2170. + break;
  2171. + }
  2172. + cryptostats.cs_rets++;
  2173. + }
  2174. + }
  2175. + CRYPTO_RETQ_UNLOCK();
  2176. + complete_and_exit(&cryptoretproc_exited, 0);
  2177. +}
  2178. +
  2179. +
  2180. +#if 0 /* should put this into /proc or something */
  2181. +static void
  2182. +db_show_drivers(void)
  2183. +{
  2184. + int hid;
  2185. +
  2186. + db_printf("%12s %4s %4s %8s %2s %2s\n"
  2187. + , "Device"
  2188. + , "Ses"
  2189. + , "Kops"
  2190. + , "Flags"
  2191. + , "QB"
  2192. + , "KB"
  2193. + );
  2194. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  2195. + const struct cryptocap *cap = &crypto_drivers[hid];
  2196. + if (cap->cc_dev == NULL)
  2197. + continue;
  2198. + db_printf("%-12s %4u %4u %08x %2u %2u\n"
  2199. + , device_get_nameunit(cap->cc_dev)
  2200. + , cap->cc_sessions
  2201. + , cap->cc_koperations
  2202. + , cap->cc_flags
  2203. + , cap->cc_qblocked
  2204. + , cap->cc_kqblocked
  2205. + );
  2206. + }
  2207. +}
  2208. +
  2209. +DB_SHOW_COMMAND(crypto, db_show_crypto)
  2210. +{
  2211. + struct cryptop *crp;
  2212. +
  2213. + db_show_drivers();
  2214. + db_printf("\n");
  2215. +
  2216. + db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
  2217. + "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
  2218. + "Desc", "Callback");
  2219. + TAILQ_FOREACH(crp, &crp_q, crp_next) {
  2220. + db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
  2221. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  2222. + , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
  2223. + , crp->crp_ilen, crp->crp_olen
  2224. + , crp->crp_etype
  2225. + , crp->crp_flags
  2226. + , crp->crp_desc
  2227. + , crp->crp_callback
  2228. + );
  2229. + }
  2230. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  2231. + db_printf("\n%4s %4s %4s %8s\n",
  2232. + "HID", "Etype", "Flags", "Callback");
  2233. + TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
  2234. + db_printf("%4u %4u %04x %8p\n"
  2235. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  2236. + , crp->crp_etype
  2237. + , crp->crp_flags
  2238. + , crp->crp_callback
  2239. + );
  2240. + }
  2241. + }
  2242. +}
  2243. +
  2244. +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
  2245. +{
  2246. + struct cryptkop *krp;
  2247. +
  2248. + db_show_drivers();
  2249. + db_printf("\n");
  2250. +
  2251. + db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
  2252. + "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
  2253. + TAILQ_FOREACH(krp, &crp_kq, krp_next) {
  2254. + db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
  2255. + , krp->krp_op
  2256. + , krp->krp_status
  2257. + , krp->krp_iparams, krp->krp_oparams
  2258. + , krp->krp_crid, krp->krp_hid
  2259. + , krp->krp_callback
  2260. + );
  2261. + }
  2262. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  2263. + db_printf("%4s %5s %8s %4s %8s\n",
  2264. + "Op", "Status", "CRID", "HID", "Callback");
  2265. + TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
  2266. + db_printf("%4u %5u %08x %4u %8p\n"
  2267. + , krp->krp_op
  2268. + , krp->krp_status
  2269. + , krp->krp_crid, krp->krp_hid
  2270. + , krp->krp_callback
  2271. + );
  2272. + }
  2273. + }
  2274. +}
  2275. +#endif
  2276. +
  2277. +
  2278. +static int
  2279. +crypto_init(void)
  2280. +{
  2281. + int error;
  2282. +
  2283. + dprintk("%s(0x%x)\n", __FUNCTION__, (int) crypto_init);
  2284. +
  2285. + if (crypto_initted)
  2286. + return 0;
  2287. + crypto_initted = 1;
  2288. +
  2289. + spin_lock_init(&crypto_drivers_lock);
  2290. + spin_lock_init(&crypto_q_lock);
  2291. + spin_lock_init(&crypto_ret_q_lock);
  2292. +
  2293. + cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
  2294. + 0, SLAB_HWCACHE_ALIGN, NULL
  2295. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  2296. + , NULL
  2297. +#endif
  2298. + );
  2299. +
  2300. + cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
  2301. + 0, SLAB_HWCACHE_ALIGN, NULL
  2302. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  2303. + , NULL
  2304. +#endif
  2305. + );
  2306. +
  2307. + if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
  2308. + printk("crypto: crypto_init cannot setup crypto zones\n");
  2309. + error = ENOMEM;
  2310. + goto bad;
  2311. + }
  2312. +
  2313. + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
  2314. + crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
  2315. + GFP_KERNEL);
  2316. + if (crypto_drivers == NULL) {
  2317. + printk("crypto: crypto_init cannot setup crypto drivers\n");
  2318. + error = ENOMEM;
  2319. + goto bad;
  2320. + }
  2321. +
  2322. + memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
  2323. +
  2324. + init_completion(&cryptoproc_exited);
  2325. + init_completion(&cryptoretproc_exited);
  2326. +
  2327. + cryptoproc = 0; /* to avoid race condition where proc runs first */
  2328. + cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
  2329. + if (cryptoproc < 0) {
  2330. + error = cryptoproc;
  2331. + printk("crypto: crypto_init cannot start crypto thread; error %d",
  2332. + error);
  2333. + goto bad;
  2334. + }
  2335. +
  2336. + cryptoretproc = 0; /* to avoid race condition where proc runs first */
  2337. + cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
  2338. + if (cryptoretproc < 0) {
  2339. + error = cryptoretproc;
  2340. + printk("crypto: crypto_init cannot start cryptoret thread; error %d",
  2341. + error);
  2342. + goto bad;
  2343. + }
  2344. +
  2345. + return 0;
  2346. +bad:
  2347. + crypto_exit();
  2348. + return error;
  2349. +}
  2350. +
  2351. +
  2352. +static void
  2353. +crypto_exit(void)
  2354. +{
  2355. + pid_t p;
  2356. + unsigned long d_flags;
  2357. +
  2358. + dprintk("%s()\n", __FUNCTION__);
  2359. +
  2360. + /*
  2361. + * Terminate any crypto threads.
  2362. + */
  2363. +
  2364. + CRYPTO_DRIVER_LOCK();
  2365. + p = cryptoproc;
  2366. + cryptoproc = (pid_t) -1;
  2367. + kill_pid(p, SIGTERM, 1);
  2368. + wake_up_interruptible(&cryptoproc_wait);
  2369. + CRYPTO_DRIVER_UNLOCK();
  2370. +
  2371. + wait_for_completion(&cryptoproc_exited);
  2372. +
  2373. + CRYPTO_DRIVER_LOCK();
  2374. + p = cryptoretproc;
  2375. + cryptoretproc = (pid_t) -1;
  2376. + kill_pid(p, SIGTERM, 1);
  2377. + wake_up_interruptible(&cryptoretproc_wait);
  2378. + CRYPTO_DRIVER_UNLOCK();
  2379. +
  2380. + wait_for_completion(&cryptoretproc_exited);
  2381. +
  2382. + /* XXX flush queues??? */
  2383. +
  2384. + /*
  2385. + * Reclaim dynamically allocated resources.
  2386. + */
  2387. + if (crypto_drivers != NULL)
  2388. + kfree(crypto_drivers);
  2389. +
  2390. + if (cryptodesc_zone != NULL)
  2391. + kmem_cache_destroy(cryptodesc_zone);
  2392. + if (cryptop_zone != NULL)
  2393. + kmem_cache_destroy(cryptop_zone);
  2394. +}
  2395. +
  2396. +
  2397. +EXPORT_SYMBOL(crypto_newsession);
  2398. +EXPORT_SYMBOL(crypto_freesession);
  2399. +EXPORT_SYMBOL(crypto_get_driverid);
  2400. +EXPORT_SYMBOL(crypto_kregister);
  2401. +EXPORT_SYMBOL(crypto_register);
  2402. +EXPORT_SYMBOL(crypto_unregister);
  2403. +EXPORT_SYMBOL(crypto_unregister_all);
  2404. +EXPORT_SYMBOL(crypto_unblock);
  2405. +EXPORT_SYMBOL(crypto_dispatch);
  2406. +EXPORT_SYMBOL(crypto_kdispatch);
  2407. +EXPORT_SYMBOL(crypto_freereq);
  2408. +EXPORT_SYMBOL(crypto_getreq);
  2409. +EXPORT_SYMBOL(crypto_done);
  2410. +EXPORT_SYMBOL(crypto_kdone);
  2411. +EXPORT_SYMBOL(crypto_getfeat);
  2412. +EXPORT_SYMBOL(crypto_userasymcrypto);
  2413. +EXPORT_SYMBOL(crypto_getcaps);
  2414. +EXPORT_SYMBOL(crypto_find_driver);
  2415. +EXPORT_SYMBOL(crypto_find_device_byhid);
  2416. +
  2417. +module_init(crypto_init);
  2418. +module_exit(crypto_exit);
  2419. +
  2420. +MODULE_LICENSE("BSD");
  2421. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  2422. +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
  2423. diff -Nur linux-2.6.29.1.orig/crypto/ocf/cryptodev.c linux-2.6.29.1/crypto/ocf/cryptodev.c
  2424. --- linux-2.6.29.1.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
  2425. +++ linux-2.6.29.1/crypto/ocf/cryptodev.c 2009-04-20 20:01:21.412551214 +0200
  2426. @@ -0,0 +1,1048 @@
  2427. +/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
  2428. +
  2429. +/*-
  2430. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  2431. + * Copyright (C) 2006-2007 David McCullough
  2432. + * Copyright (C) 2004-2005 Intel Corporation.
  2433. + * The license and original author are listed below.
  2434. + *
  2435. + * Copyright (c) 2001 Theo de Raadt
  2436. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  2437. + *
  2438. + * Redistribution and use in source and binary forms, with or without
  2439. + * modification, are permitted provided that the following conditions
  2440. + * are met:
  2441. + *
  2442. + * 1. Redistributions of source code must retain the above copyright
  2443. + * notice, this list of conditions and the following disclaimer.
  2444. + * 2. Redistributions in binary form must reproduce the above copyright
  2445. + * notice, this list of conditions and the following disclaimer in the
  2446. + * documentation and/or other materials provided with the distribution.
  2447. + * 3. The name of the author may not be used to endorse or promote products
  2448. + * derived from this software without specific prior written permission.
  2449. + *
  2450. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2451. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2452. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2453. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2454. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2455. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2456. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2457. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2458. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2459. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2460. + *
  2461. + * Effort sponsored in part by the Defense Advanced Research Projects
  2462. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  2463. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  2464. + *
  2465. +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
  2466. + */
  2467. +
  2468. +#ifndef AUTOCONF_INCLUDED
  2469. +#include <linux/config.h>
  2470. +#endif
  2471. +#include <linux/types.h>
  2472. +#include <linux/time.h>
  2473. +#include <linux/delay.h>
  2474. +#include <linux/list.h>
  2475. +#include <linux/init.h>
  2476. +#include <linux/sched.h>
  2477. +#include <linux/unistd.h>
  2478. +#include <linux/module.h>
  2479. +#include <linux/wait.h>
  2480. +#include <linux/slab.h>
  2481. +#include <linux/fs.h>
  2482. +#include <linux/dcache.h>
  2483. +#include <linux/file.h>
  2484. +#include <linux/mount.h>
  2485. +#include <linux/miscdevice.h>
  2486. +#include <linux/version.h>
  2487. +#include <asm/uaccess.h>
  2488. +
  2489. +#include <cryptodev.h>
  2490. +#include <uio.h>
  2491. +
  2492. +extern asmlinkage long sys_dup(unsigned int fildes);
  2493. +
  2494. +#define debug cryptodev_debug
  2495. +int cryptodev_debug = 0;
  2496. +module_param(cryptodev_debug, int, 0644);
  2497. +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
  2498. +
  2499. +struct csession_info {
  2500. + u_int16_t blocksize;
  2501. + u_int16_t minkey, maxkey;
  2502. +
  2503. + u_int16_t keysize;
  2504. + /* u_int16_t hashsize; */
  2505. + u_int16_t authsize;
  2506. + /* u_int16_t ctxsize; */
  2507. +};
  2508. +
  2509. +struct csession {
  2510. + struct list_head list;
  2511. + u_int64_t sid;
  2512. + u_int32_t ses;
  2513. +
  2514. + wait_queue_head_t waitq;
  2515. +
  2516. + u_int32_t cipher;
  2517. +
  2518. + u_int32_t mac;
  2519. +
  2520. + caddr_t key;
  2521. + int keylen;
  2522. + u_char tmp_iv[EALG_MAX_BLOCK_LEN];
  2523. +
  2524. + caddr_t mackey;
  2525. + int mackeylen;
  2526. +
  2527. + struct csession_info info;
  2528. +
  2529. + struct iovec iovec;
  2530. + struct uio uio;
  2531. + int error;
  2532. +};
  2533. +
  2534. +struct fcrypt {
  2535. + struct list_head csessions;
  2536. + int sesn;
  2537. +};
  2538. +
  2539. +static struct csession *csefind(struct fcrypt *, u_int);
  2540. +static int csedelete(struct fcrypt *, struct csession *);
  2541. +static struct csession *cseadd(struct fcrypt *, struct csession *);
  2542. +static struct csession *csecreate(struct fcrypt *, u_int64_t,
  2543. + struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
  2544. +static int csefree(struct csession *);
  2545. +
  2546. +static int cryptodev_op(struct csession *, struct crypt_op *);
  2547. +static int cryptodev_key(struct crypt_kop *);
  2548. +static int cryptodev_find(struct crypt_find_op *);
  2549. +
  2550. +static int cryptodev_cb(void *);
  2551. +static int cryptodev_open(struct inode *inode, struct file *filp);
  2552. +
  2553. +/*
  2554. + * Check a crypto identifier to see if it requested
  2555. + * a valid crid and it's capabilities match.
  2556. + */
  2557. +static int
  2558. +checkcrid(int crid)
  2559. +{
  2560. + int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  2561. + int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  2562. + int caps = 0;
  2563. +
  2564. + /* if the user hasn't selected a driver, then just call newsession */
  2565. + if (hid == 0 && typ != 0)
  2566. + return 0;
  2567. +
  2568. + caps = crypto_getcaps(hid);
  2569. +
  2570. + /* didn't find anything with capabilities */
  2571. + if (caps == 0) {
  2572. + dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
  2573. + return EINVAL;
  2574. + }
  2575. +
  2576. + /* the user didn't specify SW or HW, so the driver is ok */
  2577. + if (typ == 0)
  2578. + return 0;
  2579. +
  2580. + /* if the type specified didn't match */
  2581. + if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
  2582. + dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
  2583. + hid, typ, caps);
  2584. + return EINVAL;
  2585. + }
  2586. +
  2587. + return 0;
  2588. +}
  2589. +
  2590. +static int
  2591. +cryptodev_op(struct csession *cse, struct crypt_op *cop)
  2592. +{
  2593. + struct cryptop *crp = NULL;
  2594. + struct cryptodesc *crde = NULL, *crda = NULL;
  2595. + int error = 0;
  2596. +
  2597. + dprintk("%s()\n", __FUNCTION__);
  2598. + if (cop->len > CRYPTO_MAX_DATA_LEN) {
  2599. + dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
  2600. + return (E2BIG);
  2601. + }
  2602. +
  2603. + if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
  2604. + dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
  2605. + cop->len);
  2606. + return (EINVAL);
  2607. + }
  2608. +
  2609. + cse->uio.uio_iov = &cse->iovec;
  2610. + cse->uio.uio_iovcnt = 1;
  2611. + cse->uio.uio_offset = 0;
  2612. +#if 0
  2613. + cse->uio.uio_resid = cop->len;
  2614. + cse->uio.uio_segflg = UIO_SYSSPACE;
  2615. + cse->uio.uio_rw = UIO_WRITE;
  2616. + cse->uio.uio_td = td;
  2617. +#endif
  2618. + cse->uio.uio_iov[0].iov_len = cop->len;
  2619. + if (cse->info.authsize)
  2620. + cse->uio.uio_iov[0].iov_len += cse->info.authsize;
  2621. + cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
  2622. + GFP_KERNEL);
  2623. +
  2624. + if (cse->uio.uio_iov[0].iov_base == NULL) {
  2625. + dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
  2626. + cse->uio.uio_iov[0].iov_len);
  2627. + return (ENOMEM);
  2628. + }
  2629. +
  2630. + crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
  2631. + if (crp == NULL) {
  2632. + dprintk("%s: ENOMEM\n", __FUNCTION__);
  2633. + error = ENOMEM;
  2634. + goto bail;
  2635. + }
  2636. +
  2637. + if (cse->info.authsize) {
  2638. + crda = crp->crp_desc;
  2639. + if (cse->info.blocksize)
  2640. + crde = crda->crd_next;
  2641. + } else {
  2642. + if (cse->info.blocksize)
  2643. + crde = crp->crp_desc;
  2644. + else {
  2645. + dprintk("%s: bad request\n", __FUNCTION__);
  2646. + error = EINVAL;
  2647. + goto bail;
  2648. + }
  2649. + }
  2650. +
  2651. + if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
  2652. + cop->len))) {
  2653. + dprintk("%s: bad copy\n", __FUNCTION__);
  2654. + goto bail;
  2655. + }
  2656. +
  2657. + if (crda) {
  2658. + crda->crd_skip = 0;
  2659. + crda->crd_len = cop->len;
  2660. + crda->crd_inject = cop->len;
  2661. +
  2662. + crda->crd_alg = cse->mac;
  2663. + crda->crd_key = cse->mackey;
  2664. + crda->crd_klen = cse->mackeylen * 8;
  2665. + }
  2666. +
  2667. + if (crde) {
  2668. + if (cop->op == COP_ENCRYPT)
  2669. + crde->crd_flags |= CRD_F_ENCRYPT;
  2670. + else
  2671. + crde->crd_flags &= ~CRD_F_ENCRYPT;
  2672. + crde->crd_len = cop->len;
  2673. + crde->crd_inject = 0;
  2674. +
  2675. + crde->crd_alg = cse->cipher;
  2676. + crde->crd_key = cse->key;
  2677. + crde->crd_klen = cse->keylen * 8;
  2678. + }
  2679. +
  2680. + crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
  2681. + crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
  2682. + | (cop->flags & COP_F_BATCH);
  2683. + crp->crp_buf = (caddr_t)&cse->uio;
  2684. + crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
  2685. + crp->crp_sid = cse->sid;
  2686. + crp->crp_opaque = (void *)cse;
  2687. +
  2688. + if (cop->iv) {
  2689. + if (crde == NULL) {
  2690. + error = EINVAL;
  2691. + dprintk("%s no crde\n", __FUNCTION__);
  2692. + goto bail;
  2693. + }
  2694. + if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  2695. + error = EINVAL;
  2696. + dprintk("%s arc4 with IV\n", __FUNCTION__);
  2697. + goto bail;
  2698. + }
  2699. + if ((error = copy_from_user(cse->tmp_iv, cop->iv,
  2700. + cse->info.blocksize))) {
  2701. + dprintk("%s bad iv copy\n", __FUNCTION__);
  2702. + goto bail;
  2703. + }
  2704. + memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
  2705. + crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  2706. + crde->crd_skip = 0;
  2707. + } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  2708. + crde->crd_skip = 0;
  2709. + } else if (crde) {
  2710. + crde->crd_flags |= CRD_F_IV_PRESENT;
  2711. + crde->crd_skip = cse->info.blocksize;
  2712. + crde->crd_len -= cse->info.blocksize;
  2713. + }
  2714. +
  2715. + if (cop->mac && crda == NULL) {
  2716. + error = EINVAL;
  2717. + dprintk("%s no crda\n", __FUNCTION__);
  2718. + goto bail;
  2719. + }
  2720. +
  2721. + /*
  2722. + * Let the dispatch run unlocked, then, interlock against the
  2723. + * callback before checking if the operation completed and going
  2724. + * to sleep. This insures drivers don't inherit our lock which
  2725. + * results in a lock order reversal between crypto_dispatch forced
  2726. + * entry and the crypto_done callback into us.
  2727. + */
  2728. + error = crypto_dispatch(crp);
  2729. + if (error == 0) {
  2730. + dprintk("%s about to WAIT\n", __FUNCTION__);
  2731. + /*
  2732. + * we really need to wait for driver to complete to maintain
  2733. + * state, luckily interrupts will be remembered
  2734. + */
  2735. + do {
  2736. + error = wait_event_interruptible(crp->crp_waitq,
  2737. + ((crp->crp_flags & CRYPTO_F_DONE) != 0));
  2738. + /*
  2739. + * we can't break out of this loop or we will leave behind
  2740. + * a huge mess, however, staying here means if your driver
  2741. + * is broken user applications can hang and not be killed.
  2742. + * The solution, fix your driver :-)
  2743. + */
  2744. + if (error) {
  2745. + schedule();
  2746. + error = 0;
  2747. + }
  2748. + } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
  2749. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  2750. + }
  2751. +
  2752. + if (crp->crp_etype != 0) {
  2753. + error = crp->crp_etype;
  2754. + dprintk("%s error in crp processing\n", __FUNCTION__);
  2755. + goto bail;
  2756. + }
  2757. +
  2758. + if (cse->error) {
  2759. + error = cse->error;
  2760. + dprintk("%s error in cse processing\n", __FUNCTION__);
  2761. + goto bail;
  2762. + }
  2763. +
  2764. + if (cop->dst && (error = copy_to_user(cop->dst,
  2765. + cse->uio.uio_iov[0].iov_base, cop->len))) {
  2766. + dprintk("%s bad dst copy\n", __FUNCTION__);
  2767. + goto bail;
  2768. + }
  2769. +
  2770. + if (cop->mac &&
  2771. + (error=copy_to_user(cop->mac,
  2772. + (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
  2773. + cse->info.authsize))) {
  2774. + dprintk("%s bad mac copy\n", __FUNCTION__);
  2775. + goto bail;
  2776. + }
  2777. +
  2778. +bail:
  2779. + if (crp)
  2780. + crypto_freereq(crp);
  2781. + if (cse->uio.uio_iov[0].iov_base)
  2782. + kfree(cse->uio.uio_iov[0].iov_base);
  2783. +
  2784. + return (error);
  2785. +}
  2786. +
  2787. +static int
  2788. +cryptodev_cb(void *op)
  2789. +{
  2790. + struct cryptop *crp = (struct cryptop *) op;
  2791. + struct csession *cse = (struct csession *)crp->crp_opaque;
  2792. + int error;
  2793. +
  2794. + dprintk("%s()\n", __FUNCTION__);
  2795. + error = crp->crp_etype;
  2796. + if (error == EAGAIN) {
  2797. + crp->crp_flags &= ~CRYPTO_F_DONE;
  2798. +#ifdef NOTYET
  2799. + /*
  2800. + * DAVIDM I am fairly sure that we should turn this into a batch
  2801. + * request to stop bad karma/lockup, revisit
  2802. + */
  2803. + crp->crp_flags |= CRYPTO_F_BATCH;
  2804. +#endif
  2805. + return crypto_dispatch(crp);
  2806. + }
  2807. + if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
  2808. + cse->error = error;
  2809. + wake_up_interruptible(&crp->crp_waitq);
  2810. + }
  2811. + return (0);
  2812. +}
  2813. +
  2814. +static int
  2815. +cryptodevkey_cb(void *op)
  2816. +{
  2817. + struct cryptkop *krp = (struct cryptkop *) op;
  2818. + dprintk("%s()\n", __FUNCTION__);
  2819. + wake_up_interruptible(&krp->krp_waitq);
  2820. + return (0);
  2821. +}
  2822. +
  2823. +static int
  2824. +cryptodev_key(struct crypt_kop *kop)
  2825. +{
  2826. + struct cryptkop *krp = NULL;
  2827. + int error = EINVAL;
  2828. + int in, out, size, i;
  2829. +
  2830. + dprintk("%s()\n", __FUNCTION__);
  2831. + if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
  2832. + dprintk("%s params too big\n", __FUNCTION__);
  2833. + return (EFBIG);
  2834. + }
  2835. +
  2836. + in = kop->crk_iparams;
  2837. + out = kop->crk_oparams;
  2838. + switch (kop->crk_op) {
  2839. + case CRK_MOD_EXP:
  2840. + if (in == 3 && out == 1)
  2841. + break;
  2842. + return (EINVAL);
  2843. + case CRK_MOD_EXP_CRT:
  2844. + if (in == 6 && out == 1)
  2845. + break;
  2846. + return (EINVAL);
  2847. + case CRK_DSA_SIGN:
  2848. + if (in == 5 && out == 2)
  2849. + break;
  2850. + return (EINVAL);
  2851. + case CRK_DSA_VERIFY:
  2852. + if (in == 7 && out == 0)
  2853. + break;
  2854. + return (EINVAL);
  2855. + case CRK_DH_COMPUTE_KEY:
  2856. + if (in == 3 && out == 1)
  2857. + break;
  2858. + return (EINVAL);
  2859. + default:
  2860. + return (EINVAL);
  2861. + }
  2862. +
  2863. + krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
  2864. + if (!krp)
  2865. + return (ENOMEM);
  2866. + bzero(krp, sizeof *krp);
  2867. + krp->krp_op = kop->crk_op;
  2868. + krp->krp_status = kop->crk_status;
  2869. + krp->krp_iparams = kop->crk_iparams;
  2870. + krp->krp_oparams = kop->crk_oparams;
  2871. + krp->krp_crid = kop->crk_crid;
  2872. + krp->krp_status = 0;
  2873. + krp->krp_flags = CRYPTO_KF_CBIMM;
  2874. + krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
  2875. + init_waitqueue_head(&krp->krp_waitq);
  2876. +
  2877. + for (i = 0; i < CRK_MAXPARAM; i++)
  2878. + krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
  2879. + for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
  2880. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  2881. + if (size == 0)
  2882. + continue;
  2883. + krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
  2884. + if (i >= krp->krp_iparams)
  2885. + continue;
  2886. + error = copy_from_user(krp->krp_param[i].crp_p,
  2887. + kop->crk_param[i].crp_p, size);
  2888. + if (error)
  2889. + goto fail;
  2890. + }
  2891. +
  2892. + error = crypto_kdispatch(krp);
  2893. + if (error)
  2894. + goto fail;
  2895. +
  2896. + do {
  2897. + error = wait_event_interruptible(krp->krp_waitq,
  2898. + ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
  2899. + /*
  2900. + * we can't break out of this loop or we will leave behind
  2901. + * a huge mess, however, staying here means if your driver
  2902. + * is broken user applications can hang and not be killed.
  2903. + * The solution, fix your driver :-)
  2904. + */
  2905. + if (error) {
  2906. + schedule();
  2907. + error = 0;
  2908. + }
  2909. + } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
  2910. +
  2911. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  2912. +
  2913. + kop->crk_crid = krp->krp_crid; /* device that did the work */
  2914. + if (krp->krp_status != 0) {
  2915. + error = krp->krp_status;
  2916. + goto fail;
  2917. + }
  2918. +
  2919. + for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
  2920. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  2921. + if (size == 0)
  2922. + continue;
  2923. + error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
  2924. + size);
  2925. + if (error)
  2926. + goto fail;
  2927. + }
  2928. +
  2929. +fail:
  2930. + if (krp) {
  2931. + kop->crk_status = krp->krp_status;
  2932. + for (i = 0; i < CRK_MAXPARAM; i++) {
  2933. + if (krp->krp_param[i].crp_p)
  2934. + kfree(krp->krp_param[i].crp_p);
  2935. + }
  2936. + kfree(krp);
  2937. + }
  2938. + return (error);
  2939. +}
  2940. +
  2941. +static int
  2942. +cryptodev_find(struct crypt_find_op *find)
  2943. +{
  2944. + device_t dev;
  2945. +
  2946. + if (find->crid != -1) {
  2947. + dev = crypto_find_device_byhid(find->crid);
  2948. + if (dev == NULL)
  2949. + return (ENOENT);
  2950. + strlcpy(find->name, device_get_nameunit(dev),
  2951. + sizeof(find->name));
  2952. + } else {
  2953. + find->crid = crypto_find_driver(find->name);
  2954. + if (find->crid == -1)
  2955. + return (ENOENT);
  2956. + }
  2957. + return (0);
  2958. +}
  2959. +
  2960. +static struct csession *
  2961. +csefind(struct fcrypt *fcr, u_int ses)
  2962. +{
  2963. + struct csession *cse;
  2964. +
  2965. + dprintk("%s()\n", __FUNCTION__);
  2966. + list_for_each_entry(cse, &fcr->csessions, list)
  2967. + if (cse->ses == ses)
  2968. + return (cse);
  2969. + return (NULL);
  2970. +}
  2971. +
  2972. +static int
  2973. +csedelete(struct fcrypt *fcr, struct csession *cse_del)
  2974. +{
  2975. + struct csession *cse;
  2976. +
  2977. + dprintk("%s()\n", __FUNCTION__);
  2978. + list_for_each_entry(cse, &fcr->csessions, list) {
  2979. + if (cse == cse_del) {
  2980. + list_del(&cse->list);
  2981. + return (1);
  2982. + }
  2983. + }
  2984. + return (0);
  2985. +}
  2986. +
  2987. +static struct csession *
  2988. +cseadd(struct fcrypt *fcr, struct csession *cse)
  2989. +{
  2990. + dprintk("%s()\n", __FUNCTION__);
  2991. + list_add_tail(&cse->list, &fcr->csessions);
  2992. + cse->ses = fcr->sesn++;
  2993. + return (cse);
  2994. +}
  2995. +
  2996. +static struct csession *
  2997. +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
  2998. + struct cryptoini *cria, struct csession_info *info)
  2999. +{
  3000. + struct csession *cse;
  3001. +
  3002. + dprintk("%s()\n", __FUNCTION__);
  3003. + cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
  3004. + if (cse == NULL)
  3005. + return NULL;
  3006. + memset(cse, 0, sizeof(struct csession));
  3007. +
  3008. + INIT_LIST_HEAD(&cse->list);
  3009. + init_waitqueue_head(&cse->waitq);
  3010. +
  3011. + cse->key = crie->cri_key;
  3012. + cse->keylen = crie->cri_klen/8;
  3013. + cse->mackey = cria->cri_key;
  3014. + cse->mackeylen = cria->cri_klen/8;
  3015. + cse->sid = sid;
  3016. + cse->cipher = crie->cri_alg;
  3017. + cse->mac = cria->cri_alg;
  3018. + cse->info = *info;
  3019. + cseadd(fcr, cse);
  3020. + return (cse);
  3021. +}
  3022. +
  3023. +static int
  3024. +csefree(struct csession *cse)
  3025. +{
  3026. + int error;
  3027. +
  3028. + dprintk("%s()\n", __FUNCTION__);
  3029. + error = crypto_freesession(cse->sid);
  3030. + if (cse->key)
  3031. + kfree(cse->key);
  3032. + if (cse->mackey)
  3033. + kfree(cse->mackey);
  3034. + kfree(cse);
  3035. + return(error);
  3036. +}
  3037. +
  3038. +static int
  3039. +cryptodev_ioctl(
  3040. + struct inode *inode,
  3041. + struct file *filp,
  3042. + unsigned int cmd,
  3043. + unsigned long arg)
  3044. +{
  3045. + struct cryptoini cria, crie;
  3046. + struct fcrypt *fcr = filp->private_data;
  3047. + struct csession *cse;
  3048. + struct csession_info info;
  3049. + struct session2_op sop;
  3050. + struct crypt_op cop;
  3051. + struct crypt_kop kop;
  3052. + struct crypt_find_op fop;
  3053. + u_int64_t sid;
  3054. + u_int32_t ses;
  3055. + int feat, fd, error = 0, crid;
  3056. + mm_segment_t fs;
  3057. +
  3058. + dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
  3059. +
  3060. + switch (cmd) {
  3061. +
  3062. + case CRIOGET: {
  3063. + dprintk("%s(CRIOGET)\n", __FUNCTION__);
  3064. + fs = get_fs();
  3065. + set_fs(get_ds());
  3066. + for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
  3067. + if (files_fdtable(current->files)->fd[fd] == filp)
  3068. + break;
  3069. + fd = sys_dup(fd);
  3070. + set_fs(fs);
  3071. + put_user(fd, (int *) arg);
  3072. + return IS_ERR_VALUE(fd) ? fd : 0;
  3073. + }
  3074. +
  3075. +#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
  3076. + case CIOCGSESSION:
  3077. + case CIOCGSESSION2:
  3078. + dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
  3079. + memset(&crie, 0, sizeof(crie));
  3080. + memset(&cria, 0, sizeof(cria));
  3081. + memset(&info, 0, sizeof(info));
  3082. + memset(&sop, 0, sizeof(sop));
  3083. +
  3084. + if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
  3085. + sizeof(struct session_op) : sizeof(sop))) {
  3086. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  3087. + error = EFAULT;
  3088. + goto bail;
  3089. + }
  3090. +
  3091. + switch (sop.cipher) {
  3092. + case 0:
  3093. + dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
  3094. + break;
  3095. + case CRYPTO_NULL_CBC:
  3096. + info.blocksize = NULL_BLOCK_LEN;
  3097. + info.minkey = NULL_MIN_KEY_LEN;
  3098. + info.maxkey = NULL_MAX_KEY_LEN;
  3099. + break;
  3100. + case CRYPTO_DES_CBC:
  3101. + info.blocksize = DES_BLOCK_LEN;
  3102. + info.minkey = DES_MIN_KEY_LEN;
  3103. + info.maxkey = DES_MAX_KEY_LEN;
  3104. + break;
  3105. + case CRYPTO_3DES_CBC:
  3106. + info.blocksize = DES3_BLOCK_LEN;
  3107. + info.minkey = DES3_MIN_KEY_LEN;
  3108. + info.maxkey = DES3_MAX_KEY_LEN;
  3109. + break;
  3110. + case CRYPTO_BLF_CBC:
  3111. + info.blocksize = BLOWFISH_BLOCK_LEN;
  3112. + info.minkey = BLOWFISH_MIN_KEY_LEN;
  3113. + info.maxkey = BLOWFISH_MAX_KEY_LEN;
  3114. + break;
  3115. + case CRYPTO_CAST_CBC:
  3116. + info.blocksize = CAST128_BLOCK_LEN;
  3117. + info.minkey = CAST128_MIN_KEY_LEN;
  3118. + info.maxkey = CAST128_MAX_KEY_LEN;
  3119. + break;
  3120. + case CRYPTO_SKIPJACK_CBC:
  3121. + info.blocksize = SKIPJACK_BLOCK_LEN;
  3122. + info.minkey = SKIPJACK_MIN_KEY_LEN;
  3123. + info.maxkey = SKIPJACK_MAX_KEY_LEN;
  3124. + break;
  3125. + case CRYPTO_AES_CBC:
  3126. + info.blocksize = AES_BLOCK_LEN;
  3127. + info.minkey = AES_MIN_KEY_LEN;
  3128. + info.maxkey = AES_MAX_KEY_LEN;
  3129. + break;
  3130. + case CRYPTO_ARC4:
  3131. + info.blocksize = ARC4_BLOCK_LEN;
  3132. + info.minkey = ARC4_MIN_KEY_LEN;
  3133. + info.maxkey = ARC4_MAX_KEY_LEN;
  3134. + break;
  3135. + case CRYPTO_CAMELLIA_CBC:
  3136. + info.blocksize = CAMELLIA_BLOCK_LEN;
  3137. + info.minkey = CAMELLIA_MIN_KEY_LEN;
  3138. + info.maxkey = CAMELLIA_MAX_KEY_LEN;
  3139. + break;
  3140. + default:
  3141. + dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
  3142. + error = EINVAL;
  3143. + goto bail;
  3144. + }
  3145. +
  3146. + switch (sop.mac) {
  3147. + case 0:
  3148. + dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
  3149. + break;
  3150. + case CRYPTO_NULL_HMAC:
  3151. + info.authsize = NULL_HASH_LEN;
  3152. + break;
  3153. + case CRYPTO_MD5:
  3154. + info.authsize = MD5_HASH_LEN;
  3155. + break;
  3156. + case CRYPTO_SHA1:
  3157. + info.authsize = SHA1_HASH_LEN;
  3158. + break;
  3159. + case CRYPTO_SHA2_256:
  3160. + info.authsize = SHA2_256_HASH_LEN;
  3161. + break;
  3162. + case CRYPTO_SHA2_384:
  3163. + info.authsize = SHA2_384_HASH_LEN;
  3164. + break;
  3165. + case CRYPTO_SHA2_512:
  3166. + info.authsize = SHA2_512_HASH_LEN;
  3167. + break;
  3168. + case CRYPTO_RIPEMD160:
  3169. + info.authsize = RIPEMD160_HASH_LEN;
  3170. + break;
  3171. + case CRYPTO_MD5_HMAC:
  3172. + info.authsize = MD5_HASH_LEN;
  3173. + break;
  3174. + case CRYPTO_SHA1_HMAC:
  3175. + info.authsize = SHA1_HASH_LEN;
  3176. + break;
  3177. + case CRYPTO_SHA2_256_HMAC:
  3178. + info.authsize = SHA2_256_HASH_LEN;
  3179. + break;
  3180. + case CRYPTO_SHA2_384_HMAC:
  3181. + info.authsize = SHA2_384_HASH_LEN;
  3182. + break;
  3183. + case CRYPTO_SHA2_512_HMAC:
  3184. + info.authsize = SHA2_512_HASH_LEN;
  3185. + break;
  3186. + case CRYPTO_RIPEMD160_HMAC:
  3187. + info.authsize = RIPEMD160_HASH_LEN;
  3188. + break;
  3189. + default:
  3190. + dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
  3191. + error = EINVAL;
  3192. + goto bail;
  3193. + }
  3194. +
  3195. + if (info.blocksize) {
  3196. + crie.cri_alg = sop.cipher;
  3197. + crie.cri_klen = sop.keylen * 8;
  3198. + if ((info.maxkey && sop.keylen > info.maxkey) ||
  3199. + sop.keylen < info.minkey) {
  3200. + dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
  3201. + error = EINVAL;
  3202. + goto bail;
  3203. + }
  3204. +
  3205. + crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
  3206. + if (copy_from_user(crie.cri_key, sop.key,
  3207. + crie.cri_klen/8)) {
  3208. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  3209. + error = EFAULT;
  3210. + goto bail;
  3211. + }
  3212. + if (info.authsize)
  3213. + crie.cri_next = &cria;
  3214. + }
  3215. +
  3216. + if (info.authsize) {
  3217. + cria.cri_alg = sop.mac;
  3218. + cria.cri_klen = sop.mackeylen * 8;
  3219. + if ((info.maxkey && sop.mackeylen > info.maxkey) ||
  3220. + sop.keylen < info.minkey) {
  3221. + dprintk("%s(%s) - mackeylen %d\n", __FUNCTION__, CIOCGSESSSTR,
  3222. + sop.mackeylen);
  3223. + error = EINVAL;
  3224. + goto bail;
  3225. + }
  3226. +
  3227. + if (cria.cri_klen) {
  3228. + cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
  3229. + if (copy_from_user(cria.cri_key, sop.mackey,
  3230. + cria.cri_klen / 8)) {
  3231. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  3232. + error = EFAULT;
  3233. + goto bail;
  3234. + }
  3235. + }
  3236. + }
  3237. +
  3238. + /* NB: CIOGSESSION2 has the crid */
  3239. + if (cmd == CIOCGSESSION2) {
  3240. + crid = sop.crid;
  3241. + error = checkcrid(crid);
  3242. + if (error) {
  3243. + dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
  3244. + CIOCGSESSSTR, error);
  3245. + goto bail;
  3246. + }
  3247. + } else {
  3248. + /* allow either HW or SW to be used */
  3249. + crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  3250. + }
  3251. + error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
  3252. + if (error) {
  3253. + dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
  3254. + goto bail;
  3255. + }
  3256. +
  3257. + cse = csecreate(fcr, sid, &crie, &cria, &info);
  3258. + if (cse == NULL) {
  3259. + crypto_freesession(sid);
  3260. + error = EINVAL;
  3261. + dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
  3262. + goto bail;
  3263. + }
  3264. + sop.ses = cse->ses;
  3265. +
  3266. + if (cmd == CIOCGSESSION2) {
  3267. + /* return hardware/driver id */
  3268. + sop.crid = CRYPTO_SESID2HID(cse->sid);
  3269. + }
  3270. +
  3271. + if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
  3272. + sizeof(struct session_op) : sizeof(sop))) {
  3273. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  3274. + error = EFAULT;
  3275. + }
  3276. +bail:
  3277. + if (error) {
  3278. + dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
  3279. + if (crie.cri_key)
  3280. + kfree(crie.cri_key);
  3281. + if (cria.cri_key)
  3282. + kfree(cria.cri_key);
  3283. + }
  3284. + break;
  3285. + case CIOCFSESSION:
  3286. + dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
  3287. + get_user(ses, (uint32_t*)arg);
  3288. + cse = csefind(fcr, ses);
  3289. + if (cse == NULL) {
  3290. + error = EINVAL;
  3291. + dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
  3292. + break;
  3293. + }
  3294. + csedelete(fcr, cse);
  3295. + error = csefree(cse);
  3296. + break;
  3297. + case CIOCCRYPT:
  3298. + dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
  3299. + if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
  3300. + dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
  3301. + error = EFAULT;
  3302. + goto bail;
  3303. + }
  3304. + cse = csefind(fcr, cop.ses);
  3305. + if (cse == NULL) {
  3306. + error = EINVAL;
  3307. + dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
  3308. + break;
  3309. + }
  3310. + error = cryptodev_op(cse, &cop);
  3311. + if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
  3312. + dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
  3313. + error = EFAULT;
  3314. + goto bail;
  3315. + }
  3316. + break;
  3317. + case CIOCKEY:
  3318. + case CIOCKEY2:
  3319. + dprintk("%s(CIOCKEY)\n", __FUNCTION__);
  3320. + if (!crypto_userasymcrypto)
  3321. + return (EPERM); /* XXX compat? */
  3322. + if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
  3323. + dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
  3324. + error = EFAULT;
  3325. + goto bail;
  3326. + }
  3327. + if (cmd == CIOCKEY) {
  3328. + /* NB: crypto core enforces s/w driver use */
  3329. + kop.crk_crid =
  3330. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  3331. + }
  3332. + error = cryptodev_key(&kop);
  3333. + if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
  3334. + dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
  3335. + error = EFAULT;
  3336. + goto bail;
  3337. + }
  3338. + break;
  3339. + case CIOCASYMFEAT:
  3340. + dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
  3341. + if (!crypto_userasymcrypto) {
  3342. + /*
  3343. + * NB: if user asym crypto operations are
  3344. + * not permitted return "no algorithms"
  3345. + * so well-behaved applications will just
  3346. + * fallback to doing them in software.
  3347. + */
  3348. + feat = 0;
  3349. + } else
  3350. + error = crypto_getfeat(&feat);
  3351. + if (!error) {
  3352. + error = copy_to_user((void*)arg, &feat, sizeof(feat));
  3353. + }
  3354. + break;
  3355. + case CIOCFINDDEV:
  3356. + if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
  3357. + dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
  3358. + error = EFAULT;
  3359. + goto bail;
  3360. + }
  3361. + error = cryptodev_find(&fop);
  3362. + if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
  3363. + dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
  3364. + error = EFAULT;
  3365. + goto bail;
  3366. + }
  3367. + break;
  3368. + default:
  3369. + dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
  3370. + error = EINVAL;
  3371. + break;
  3372. + }
  3373. + return(-error);
  3374. +}
  3375. +
  3376. +#ifdef HAVE_UNLOCKED_IOCTL
  3377. +static long
  3378. +cryptodev_unlocked_ioctl(
  3379. + struct file *filp,
  3380. + unsigned int cmd,
  3381. + unsigned long arg)
  3382. +{
  3383. + return cryptodev_ioctl(NULL, filp, cmd, arg);
  3384. +}
  3385. +#endif
  3386. +
  3387. +static int
  3388. +cryptodev_open(struct inode *inode, struct file *filp)
  3389. +{
  3390. + struct fcrypt *fcr;
  3391. +
  3392. + dprintk("%s()\n", __FUNCTION__);
  3393. + if (filp->private_data) {
  3394. + printk("cryptodev: Private data already exists !\n");
  3395. + return(0);
  3396. + }
  3397. +
  3398. + fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
  3399. + if (!fcr) {
  3400. + dprintk("%s() - malloc failed\n", __FUNCTION__);
  3401. + return(-ENOMEM);
  3402. + }
  3403. + memset(fcr, 0, sizeof(*fcr));
  3404. +
  3405. + INIT_LIST_HEAD(&fcr->csessions);
  3406. + filp->private_data = fcr;
  3407. + return(0);
  3408. +}
  3409. +
  3410. +static int
  3411. +cryptodev_release(struct inode *inode, struct file *filp)
  3412. +{
  3413. + struct fcrypt *fcr = filp->private_data;
  3414. + struct csession *cse, *tmp;
  3415. +
  3416. + dprintk("%s()\n", __FUNCTION__);
  3417. + if (!filp) {
  3418. + printk("cryptodev: No private data on release\n");
  3419. + return(0);
  3420. + }
  3421. +
  3422. + list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
  3423. + list_del(&cse->list);
  3424. + (void)csefree(cse);
  3425. + }
  3426. + filp->private_data = NULL;
  3427. + kfree(fcr);
  3428. + return(0);
  3429. +}
  3430. +
  3431. +static struct file_operations cryptodev_fops = {
  3432. + .owner = THIS_MODULE,
  3433. + .open = cryptodev_open,
  3434. + .release = cryptodev_release,
  3435. + .ioctl = cryptodev_ioctl,
  3436. +#ifdef HAVE_UNLOCKED_IOCTL
  3437. + .unlocked_ioctl = cryptodev_unlocked_ioctl,
  3438. +#endif
  3439. +};
  3440. +
  3441. +static struct miscdevice cryptodev = {
  3442. + .minor = CRYPTODEV_MINOR,
  3443. + .name = "crypto",
  3444. + .fops = &cryptodev_fops,
  3445. +};
  3446. +
  3447. +static int __init
  3448. +cryptodev_init(void)
  3449. +{
  3450. + int rc;
  3451. +
  3452. + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
  3453. + rc = misc_register(&cryptodev);
  3454. + if (rc) {
  3455. + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
  3456. + return(rc);
  3457. + }
  3458. +
  3459. + return(0);
  3460. +}
  3461. +
  3462. +static void __exit
  3463. +cryptodev_exit(void)
  3464. +{
  3465. + dprintk("%s()\n", __FUNCTION__);
  3466. + misc_deregister(&cryptodev);
  3467. +}
  3468. +
  3469. +module_init(cryptodev_init);
  3470. +module_exit(cryptodev_exit);
  3471. +
  3472. +MODULE_LICENSE("BSD");
  3473. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  3474. +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
  3475. diff -Nur linux-2.6.29.1.orig/crypto/ocf/cryptodev.h linux-2.6.29.1/crypto/ocf/cryptodev.h
  3476. --- linux-2.6.29.1.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
  3477. +++ linux-2.6.29.1/crypto/ocf/cryptodev.h 2009-04-20 20:01:21.416551165 +0200
  3478. @@ -0,0 +1,478 @@
  3479. +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
  3480. +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
  3481. +
  3482. +/*-
  3483. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  3484. + * Copyright (C) 2006-2007 David McCullough
  3485. + * Copyright (C) 2004-2005 Intel Corporation.
  3486. + * The license and original author are listed below.
  3487. + *
  3488. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  3489. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  3490. + *
  3491. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  3492. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  3493. + * supported the development of this code.
  3494. + *
  3495. + * Copyright (c) 2000 Angelos D. Keromytis
  3496. + *
  3497. + * Permission to use, copy, and modify this software with or without fee
  3498. + * is hereby granted, provided that this entire notice is included in
  3499. + * all source code copies of any software which is or includes a copy or
  3500. + * modification of this software.
  3501. + *
  3502. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  3503. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  3504. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  3505. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  3506. + * PURPOSE.
  3507. + *
  3508. + * Copyright (c) 2001 Theo de Raadt
  3509. + *
  3510. + * Redistribution and use in source and binary forms, with or without
  3511. + * modification, are permitted provided that the following conditions
  3512. + * are met:
  3513. + *
  3514. + * 1. Redistributions of source code must retain the above copyright
  3515. + * notice, this list of conditions and the following disclaimer.
  3516. + * 2. Redistributions in binary form must reproduce the above copyright
  3517. + * notice, this list of conditions and the following disclaimer in the
  3518. + * documentation and/or other materials provided with the distribution.
  3519. + * 3. The name of the author may not be used to endorse or promote products
  3520. + * derived from this software without specific prior written permission.
  3521. + *
  3522. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  3523. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  3524. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  3525. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  3526. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  3527. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  3528. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  3529. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  3530. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  3531. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  3532. + *
  3533. + * Effort sponsored in part by the Defense Advanced Research Projects
  3534. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  3535. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  3536. + *
  3537. + */
  3538. +
  3539. +#ifndef _CRYPTO_CRYPTO_H_
  3540. +#define _CRYPTO_CRYPTO_H_
  3541. +
  3542. +/* Some initial values */
  3543. +#define CRYPTO_DRIVERS_INITIAL 4
  3544. +#define CRYPTO_SW_SESSIONS 32
  3545. +
  3546. +/* Hash values */
  3547. +#define NULL_HASH_LEN 0
  3548. +#define MD5_HASH_LEN 16
  3549. +#define SHA1_HASH_LEN 20
  3550. +#define RIPEMD160_HASH_LEN 20
  3551. +#define SHA2_256_HASH_LEN 32
  3552. +#define SHA2_384_HASH_LEN 48
  3553. +#define SHA2_512_HASH_LEN 64
  3554. +#define MD5_KPDK_HASH_LEN 16
  3555. +#define SHA1_KPDK_HASH_LEN 20
  3556. +/* Maximum hash algorithm result length */
  3557. +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
  3558. +
  3559. +/* HMAC values */
  3560. +#define NULL_HMAC_BLOCK_LEN 1
  3561. +#define MD5_HMAC_BLOCK_LEN 64
  3562. +#define SHA1_HMAC_BLOCK_LEN 64
  3563. +#define RIPEMD160_HMAC_BLOCK_LEN 64
  3564. +#define SHA2_256_HMAC_BLOCK_LEN 64
  3565. +#define SHA2_384_HMAC_BLOCK_LEN 128
  3566. +#define SHA2_512_HMAC_BLOCK_LEN 128
  3567. +/* Maximum HMAC block length */
  3568. +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
  3569. +#define HMAC_IPAD_VAL 0x36
  3570. +#define HMAC_OPAD_VAL 0x5C
  3571. +
  3572. +/* Encryption algorithm block sizes */
  3573. +#define NULL_BLOCK_LEN 1
  3574. +#define DES_BLOCK_LEN 8
  3575. +#define DES3_BLOCK_LEN 8
  3576. +#define BLOWFISH_BLOCK_LEN 8
  3577. +#define SKIPJACK_BLOCK_LEN 8
  3578. +#define CAST128_BLOCK_LEN 8
  3579. +#define RIJNDAEL128_BLOCK_LEN 16
  3580. +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
  3581. +#define CAMELLIA_BLOCK_LEN 16
  3582. +#define ARC4_BLOCK_LEN 1
  3583. +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
  3584. +
  3585. +/* Encryption algorithm min and max key sizes */
  3586. +#define NULL_MIN_KEY_LEN 0
  3587. +#define NULL_MAX_KEY_LEN 0
  3588. +#define DES_MIN_KEY_LEN 8
  3589. +#define DES_MAX_KEY_LEN 8
  3590. +#define DES3_MIN_KEY_LEN 24
  3591. +#define DES3_MAX_KEY_LEN 24
  3592. +#define BLOWFISH_MIN_KEY_LEN 4
  3593. +#define BLOWFISH_MAX_KEY_LEN 56
  3594. +#define SKIPJACK_MIN_KEY_LEN 10
  3595. +#define SKIPJACK_MAX_KEY_LEN 10
  3596. +#define CAST128_MIN_KEY_LEN 5
  3597. +#define CAST128_MAX_KEY_LEN 16
  3598. +#define RIJNDAEL128_MIN_KEY_LEN 16
  3599. +#define RIJNDAEL128_MAX_KEY_LEN 32
  3600. +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
  3601. +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
  3602. +#define CAMELLIA_MIN_KEY_LEN 16
  3603. +#define CAMELLIA_MAX_KEY_LEN 32
  3604. +#define ARC4_MIN_KEY_LEN 1
  3605. +#define ARC4_MAX_KEY_LEN 256
  3606. +
  3607. +/* Max size of data that can be processed */
  3608. +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
  3609. +
  3610. +#define CRYPTO_ALGORITHM_MIN 1
  3611. +#define CRYPTO_DES_CBC 1
  3612. +#define CRYPTO_3DES_CBC 2
  3613. +#define CRYPTO_BLF_CBC 3
  3614. +#define CRYPTO_CAST_CBC 4
  3615. +#define CRYPTO_SKIPJACK_CBC 5
  3616. +#define CRYPTO_MD5_HMAC 6
  3617. +#define CRYPTO_SHA1_HMAC 7
  3618. +#define CRYPTO_RIPEMD160_HMAC 8
  3619. +#define CRYPTO_MD5_KPDK 9
  3620. +#define CRYPTO_SHA1_KPDK 10
  3621. +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
  3622. +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
  3623. +#define CRYPTO_ARC4 12
  3624. +#define CRYPTO_MD5 13
  3625. +#define CRYPTO_SHA1 14
  3626. +#define CRYPTO_NULL_HMAC 15
  3627. +#define CRYPTO_NULL_CBC 16
  3628. +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
  3629. +#define CRYPTO_SHA2_256_HMAC 18
  3630. +#define CRYPTO_SHA2_384_HMAC 19
  3631. +#define CRYPTO_SHA2_512_HMAC 20
  3632. +#define CRYPTO_CAMELLIA_CBC 21
  3633. +#define CRYPTO_SHA2_256 22
  3634. +#define CRYPTO_SHA2_384 23
  3635. +#define CRYPTO_SHA2_512 24
  3636. +#define CRYPTO_RIPEMD160 25
  3637. +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
  3638. +
  3639. +/* Algorithm flags */
  3640. +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
  3641. +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
  3642. +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
  3643. +
  3644. +/*
  3645. + * Crypto driver/device flags. They can set in the crid
  3646. + * parameter when creating a session or submitting a key
  3647. + * op to affect the device/driver assigned. If neither
  3648. + * of these are specified then the crid is assumed to hold
  3649. + * the driver id of an existing (and suitable) device that
  3650. + * must be used to satisfy the request.
  3651. + */
  3652. +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
  3653. +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
  3654. +
  3655. +/* NB: deprecated */
  3656. +struct session_op {
  3657. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  3658. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  3659. +
  3660. + u_int32_t keylen; /* cipher key */
  3661. + caddr_t key;
  3662. + int mackeylen; /* mac key */
  3663. + caddr_t mackey;
  3664. +
  3665. + u_int32_t ses; /* returns: session # */
  3666. +};
  3667. +
  3668. +struct session2_op {
  3669. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  3670. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  3671. +
  3672. + u_int32_t keylen; /* cipher key */
  3673. + caddr_t key;
  3674. + int mackeylen; /* mac key */
  3675. + caddr_t mackey;
  3676. +
  3677. + u_int32_t ses; /* returns: session # */
  3678. + int crid; /* driver id + flags (rw) */
  3679. + int pad[4]; /* for future expansion */
  3680. +};
  3681. +
  3682. +struct crypt_op {
  3683. + u_int32_t ses;
  3684. + u_int16_t op; /* i.e. COP_ENCRYPT */
  3685. +#define COP_NONE 0
  3686. +#define COP_ENCRYPT 1
  3687. +#define COP_DECRYPT 2
  3688. + u_int16_t flags;
  3689. +#define COP_F_BATCH 0x0008 /* Batch op if possible */
  3690. + u_int len;
  3691. + caddr_t src, dst; /* become iov[] inside kernel */
  3692. + caddr_t mac; /* must be big enough for chosen MAC */
  3693. + caddr_t iv;
  3694. +};
  3695. +
  3696. +/*
  3697. + * Parameters for looking up a crypto driver/device by
  3698. + * device name or by id. The latter are returned for
  3699. + * created sessions (crid) and completed key operations.
  3700. + */
  3701. +struct crypt_find_op {
  3702. + int crid; /* driver id + flags */
  3703. + char name[32]; /* device/driver name */
  3704. +};
  3705. +
  3706. +/* bignum parameter, in packed bytes, ... */
  3707. +struct crparam {
  3708. + caddr_t crp_p;
  3709. + u_int crp_nbits;
  3710. +};
  3711. +
  3712. +#define CRK_MAXPARAM 8
  3713. +
  3714. +struct crypt_kop {
  3715. + u_int crk_op; /* ie. CRK_MOD_EXP or other */
  3716. + u_int crk_status; /* return status */
  3717. + u_short crk_iparams; /* # of input parameters */
  3718. + u_short crk_oparams; /* # of output parameters */
  3719. + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
  3720. + struct crparam crk_param[CRK_MAXPARAM];
  3721. +};
  3722. +#define CRK_ALGORITM_MIN 0
  3723. +#define CRK_MOD_EXP 0
  3724. +#define CRK_MOD_EXP_CRT 1
  3725. +#define CRK_DSA_SIGN 2
  3726. +#define CRK_DSA_VERIFY 3
  3727. +#define CRK_DH_COMPUTE_KEY 4
  3728. +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
  3729. +
  3730. +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
  3731. +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
  3732. +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
  3733. +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
  3734. +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
  3735. +
  3736. +/*
  3737. + * done against open of /dev/crypto, to get a cloned descriptor.
  3738. + * Please use F_SETFD against the cloned descriptor.
  3739. + */
  3740. +#define CRIOGET _IOWR('c', 100, u_int32_t)
  3741. +#define CRIOASYMFEAT CIOCASYMFEAT
  3742. +#define CRIOFINDDEV CIOCFINDDEV
  3743. +
  3744. +/* the following are done against the cloned descriptor */
  3745. +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
  3746. +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
  3747. +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
  3748. +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
  3749. +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
  3750. +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
  3751. +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
  3752. +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
  3753. +
  3754. +struct cryptotstat {
  3755. + struct timespec acc; /* total accumulated time */
  3756. + struct timespec min; /* min time */
  3757. + struct timespec max; /* max time */
  3758. + u_int32_t count; /* number of observations */
  3759. +};
  3760. +
  3761. +struct cryptostats {
  3762. + u_int32_t cs_ops; /* symmetric crypto ops submitted */
  3763. + u_int32_t cs_errs; /* symmetric crypto ops that failed */
  3764. + u_int32_t cs_kops; /* asymetric/key ops submitted */
  3765. + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
  3766. + u_int32_t cs_intrs; /* crypto swi thread activations */
  3767. + u_int32_t cs_rets; /* crypto return thread activations */
  3768. + u_int32_t cs_blocks; /* symmetric op driver block */
  3769. + u_int32_t cs_kblocks; /* symmetric op driver block */
  3770. + /*
  3771. + * When CRYPTO_TIMING is defined at compile time and the
  3772. + * sysctl debug.crypto is set to 1, the crypto system will
  3773. + * accumulate statistics about how long it takes to process
  3774. + * crypto requests at various points during processing.
  3775. + */
  3776. + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
  3777. + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
  3778. + struct cryptotstat cs_cb; /* crypto_done -> callback */
  3779. + struct cryptotstat cs_finis; /* callback -> callback return */
  3780. +
  3781. + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
  3782. +};
  3783. +
  3784. +#ifdef __KERNEL__
  3785. +
  3786. +/* Standard initialization structure beginning */
  3787. +struct cryptoini {
  3788. + int cri_alg; /* Algorithm to use */
  3789. + int cri_klen; /* Key length, in bits */
  3790. + int cri_mlen; /* Number of bytes we want from the
  3791. + entire hash. 0 means all. */
  3792. + caddr_t cri_key; /* key to use */
  3793. + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
  3794. + struct cryptoini *cri_next;
  3795. +};
  3796. +
  3797. +/* Describe boundaries of a single crypto operation */
  3798. +struct cryptodesc {
  3799. + int crd_skip; /* How many bytes to ignore from start */
  3800. + int crd_len; /* How many bytes to process */
  3801. + int crd_inject; /* Where to inject results, if applicable */
  3802. + int crd_flags;
  3803. +
  3804. +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
  3805. +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
  3806. + place, so don't copy. */
  3807. +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
  3808. +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
  3809. +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
  3810. +#define CRD_F_COMP 0x0f /* Set when doing compression */
  3811. +
  3812. + struct cryptoini CRD_INI; /* Initialization/context data */
  3813. +#define crd_iv CRD_INI.cri_iv
  3814. +#define crd_key CRD_INI.cri_key
  3815. +#define crd_alg CRD_INI.cri_alg
  3816. +#define crd_klen CRD_INI.cri_klen
  3817. +
  3818. + struct cryptodesc *crd_next;
  3819. +};
  3820. +
  3821. +/* Structure describing complete operation */
  3822. +struct cryptop {
  3823. + struct list_head crp_next;
  3824. + wait_queue_head_t crp_waitq;
  3825. +
  3826. + u_int64_t crp_sid; /* Session ID */
  3827. + int crp_ilen; /* Input data total length */
  3828. + int crp_olen; /* Result total length */
  3829. +
  3830. + int crp_etype; /*
  3831. + * Error type (zero means no error).
  3832. + * All error codes except EAGAIN
  3833. + * indicate possible data corruption (as in,
  3834. + * the data have been touched). On all
  3835. + * errors, the crp_sid may have changed
  3836. + * (reset to a new one), so the caller
  3837. + * should always check and use the new
  3838. + * value on future requests.
  3839. + */
  3840. + int crp_flags;
  3841. +
  3842. +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
  3843. +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
  3844. +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
  3845. +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
  3846. +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
  3847. +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
  3848. +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
  3849. +
  3850. + caddr_t crp_buf; /* Data to be processed */
  3851. + caddr_t crp_opaque; /* Opaque pointer, passed along */
  3852. + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
  3853. +
  3854. + int (*crp_callback)(struct cryptop *); /* Callback function */
  3855. +};
  3856. +
  3857. +#define CRYPTO_BUF_CONTIG 0x0
  3858. +#define CRYPTO_BUF_IOV 0x1
  3859. +#define CRYPTO_BUF_SKBUF 0x2
  3860. +
  3861. +#define CRYPTO_OP_DECRYPT 0x0
  3862. +#define CRYPTO_OP_ENCRYPT 0x1
  3863. +
  3864. +/*
  3865. + * Hints passed to process methods.
  3866. + */
  3867. +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
  3868. +
  3869. +struct cryptkop {
  3870. + struct list_head krp_next;
  3871. + wait_queue_head_t krp_waitq;
  3872. +
  3873. + int krp_flags;
  3874. +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
  3875. +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
  3876. +
  3877. + u_int krp_op; /* ie. CRK_MOD_EXP or other */
  3878. + u_int krp_status; /* return status */
  3879. + u_short krp_iparams; /* # of input parameters */
  3880. + u_short krp_oparams; /* # of output parameters */
  3881. + u_int krp_crid; /* desired device, etc. */
  3882. + u_int32_t krp_hid;
  3883. + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
  3884. + int (*krp_callback)(struct cryptkop *);
  3885. +};
  3886. +
  3887. +#include <ocf-compat.h>
  3888. +
  3889. +/*
  3890. + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
  3891. + * is a driver-private session identifier. The upper 32 bits contain a
  3892. + * "hardware id" used by the core crypto code to identify the driver and
  3893. + * a copy of the driver's capabilities that can be used by client code to
  3894. + * optimize operation.
  3895. + */
  3896. +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
  3897. +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
  3898. +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
  3899. +
  3900. +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
  3901. +extern int crypto_freesession(u_int64_t sid);
  3902. +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
  3903. +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
  3904. +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
  3905. +extern int32_t crypto_get_driverid(device_t dev, int flags);
  3906. +extern int crypto_find_driver(const char *);
  3907. +extern device_t crypto_find_device_byhid(int hid);
  3908. +extern int crypto_getcaps(int hid);
  3909. +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  3910. + u_int32_t flags);
  3911. +extern int crypto_kregister(u_int32_t, int, u_int32_t);
  3912. +extern int crypto_unregister(u_int32_t driverid, int alg);
  3913. +extern int crypto_unregister_all(u_int32_t driverid);
  3914. +extern int crypto_dispatch(struct cryptop *crp);
  3915. +extern int crypto_kdispatch(struct cryptkop *);
  3916. +#define CRYPTO_SYMQ 0x1
  3917. +#define CRYPTO_ASYMQ 0x2
  3918. +extern int crypto_unblock(u_int32_t, int);
  3919. +extern void crypto_done(struct cryptop *crp);
  3920. +extern void crypto_kdone(struct cryptkop *);
  3921. +extern int crypto_getfeat(int *);
  3922. +
  3923. +extern void crypto_freereq(struct cryptop *crp);
  3924. +extern struct cryptop *crypto_getreq(int num);
  3925. +
  3926. +extern int crypto_usercrypto; /* userland may do crypto requests */
  3927. +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
  3928. +extern int crypto_devallowsoft; /* only use hardware crypto */
  3929. +
  3930. +/*
  3931. + * random number support, crypto_unregister_all will unregister
  3932. + */
  3933. +extern int crypto_rregister(u_int32_t driverid,
  3934. + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
  3935. +extern int crypto_runregister_all(u_int32_t driverid);
  3936. +
  3937. +/*
  3938. + * Crypto-related utility routines used mainly by drivers.
  3939. + *
  3940. + * XXX these don't really belong here; but for now they're
  3941. + * kept apart from the rest of the system.
  3942. + */
  3943. +struct uio;
  3944. +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
  3945. +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
  3946. +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
  3947. +
  3948. +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
  3949. + caddr_t in);
  3950. +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
  3951. + caddr_t out);
  3952. +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
  3953. + int (*f)(void *, void *, u_int), void *arg);
  3954. +
  3955. +#endif /* __KERNEL__ */
  3956. +#endif /* _CRYPTO_CRYPTO_H_ */
  3957. diff -Nur linux-2.6.29.1.orig/crypto/ocf/cryptosoft.c linux-2.6.29.1/crypto/ocf/cryptosoft.c
  3958. --- linux-2.6.29.1.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
  3959. +++ linux-2.6.29.1/crypto/ocf/cryptosoft.c 2009-04-20 20:01:21.428551297 +0200
  3960. @@ -0,0 +1,898 @@
  3961. +/*
  3962. + * An OCF module that uses the linux kernel cryptoapi, based on the
  3963. + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
  3964. + * but is mostly unrecognisable,
  3965. + *
  3966. + * Written by David McCullough <david_mccullough@securecomputing.com>
  3967. + * Copyright (C) 2004-2007 David McCullough
  3968. + * Copyright (C) 2004-2005 Intel Corporation.
  3969. + *
  3970. + * LICENSE TERMS
  3971. + *
  3972. + * The free distribution and use of this software in both source and binary
  3973. + * form is allowed (with or without changes) provided that:
  3974. + *
  3975. + * 1. distributions of this source code include the above copyright
  3976. + * notice, this list of conditions and the following disclaimer;
  3977. + *
  3978. + * 2. distributions in binary form include the above copyright
  3979. + * notice, this list of conditions and the following disclaimer
  3980. + * in the documentation and/or other associated materials;
  3981. + *
  3982. + * 3. the copyright holder's name is not used to endorse products
  3983. + * built using this software without specific written permission.
  3984. + *
  3985. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  3986. + * may be distributed under the terms of the GNU General Public License (GPL),
  3987. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  3988. + *
  3989. + * DISCLAIMER
  3990. + *
  3991. + * This software is provided 'as is' with no explicit or implied warranties
  3992. + * in respect of its properties, including, but not limited to, correctness
  3993. + * and/or fitness for purpose.
  3994. + * ---------------------------------------------------------------------------
  3995. + */
  3996. +
  3997. +#ifndef AUTOCONF_INCLUDED
  3998. +#include <linux/config.h>
  3999. +#endif
  4000. +#include <linux/module.h>
  4001. +#include <linux/init.h>
  4002. +#include <linux/list.h>
  4003. +#include <linux/slab.h>
  4004. +#include <linux/sched.h>
  4005. +#include <linux/wait.h>
  4006. +#include <linux/crypto.h>
  4007. +#include <linux/mm.h>
  4008. +#include <linux/skbuff.h>
  4009. +#include <linux/random.h>
  4010. +#include <linux/scatterlist.h>
  4011. +
  4012. +#include <cryptodev.h>
  4013. +#include <uio.h>
  4014. +
  4015. +struct {
  4016. + softc_device_decl sc_dev;
  4017. +} swcr_softc;
  4018. +
  4019. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  4020. +
  4021. +/* Software session entry */
  4022. +
  4023. +#define SW_TYPE_CIPHER 0
  4024. +#define SW_TYPE_HMAC 1
  4025. +#define SW_TYPE_AUTH2 2
  4026. +#define SW_TYPE_HASH 3
  4027. +#define SW_TYPE_COMP 4
  4028. +#define SW_TYPE_BLKCIPHER 5
  4029. +
  4030. +struct swcr_data {
  4031. + int sw_type;
  4032. + int sw_alg;
  4033. + struct crypto_tfm *sw_tfm;
  4034. + union {
  4035. + struct {
  4036. + char *sw_key;
  4037. + int sw_klen;
  4038. + int sw_mlen;
  4039. + } hmac;
  4040. + void *sw_comp_buf;
  4041. + } u;
  4042. + struct swcr_data *sw_next;
  4043. +};
  4044. +
  4045. +#ifndef CRYPTO_TFM_MODE_CBC
  4046. +/*
  4047. + * As of linux-2.6.21 this is no longer defined, and presumably no longer
  4048. + * needed to be passed into the crypto core code.
  4049. + */
  4050. +#define CRYPTO_TFM_MODE_CBC 0
  4051. +#define CRYPTO_TFM_MODE_ECB 0
  4052. +#endif
  4053. +
  4054. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  4055. + /*
  4056. + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
  4057. + * API into old API.
  4058. + */
  4059. +
  4060. + /* Symmetric/Block Cipher */
  4061. + struct blkcipher_desc
  4062. + {
  4063. + struct crypto_tfm *tfm;
  4064. + void *info;
  4065. + };
  4066. + #define ecb(X) #X
  4067. + #define cbc(X) #X
  4068. + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
  4069. + #define crypto_blkcipher_cast(X) X
  4070. + #define crypto_blkcipher_tfm(X) X
  4071. + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
  4072. + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
  4073. + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
  4074. + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
  4075. + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
  4076. + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  4077. + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
  4078. + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  4079. +
  4080. + /* Hash/HMAC/Digest */
  4081. + struct hash_desc
  4082. + {
  4083. + struct crypto_tfm *tfm;
  4084. + };
  4085. + #define hmac(X) #X
  4086. + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
  4087. + #define crypto_hash_cast(X) X
  4088. + #define crypto_hash_tfm(X) X
  4089. + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
  4090. + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
  4091. + #define crypto_hash_digest(W, X, Y, Z) \
  4092. + crypto_digest_digest((W)->tfm, X, sg_num, Z)
  4093. +
  4094. + /* Asymmetric Cipher */
  4095. + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
  4096. +
  4097. + /* Compression */
  4098. + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
  4099. + #define crypto_comp_tfm(X) X
  4100. + #define crypto_comp_cast(X) X
  4101. + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
  4102. +#else
  4103. + #define ecb(X) "ecb(" #X ")"
  4104. + #define cbc(X) "cbc(" #X ")"
  4105. + #define hmac(X) "hmac(" #X ")"
  4106. +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  4107. +
  4108. +struct crypto_details
  4109. +{
  4110. + char *alg_name;
  4111. + int mode;
  4112. + int sw_type;
  4113. +};
  4114. +
  4115. +/*
  4116. + * This needs to be kept updated with CRYPTO_xxx list (cryptodev.h).
  4117. + * If the Algorithm is not supported, then insert a {NULL, 0, 0} entry.
  4118. + *
  4119. + * IMPORTANT: The index to the array IS CRYPTO_xxx.
  4120. + */
  4121. +static struct crypto_details crypto_details[CRYPTO_ALGORITHM_MAX + 1] = {
  4122. + { NULL, 0, 0 },
  4123. + /* CRYPTO_xxx index starts at 1 */
  4124. + { cbc(des), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4125. + { cbc(des3_ede), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4126. + { cbc(blowfish), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4127. + { cbc(cast5), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4128. + { cbc(skipjack), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4129. + { hmac(md5), 0, SW_TYPE_HMAC },
  4130. + { hmac(sha1), 0, SW_TYPE_HMAC },
  4131. + { hmac(ripemd160), 0, SW_TYPE_HMAC },
  4132. + { "md5-kpdk??", 0, SW_TYPE_HASH },
  4133. + { "sha1-kpdk??", 0, SW_TYPE_HASH },
  4134. + { cbc(aes), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4135. + { ecb(arc4), CRYPTO_TFM_MODE_ECB, SW_TYPE_BLKCIPHER },
  4136. + { "md5", 0, SW_TYPE_HASH },
  4137. + { "sha1", 0, SW_TYPE_HASH },
  4138. + { hmac(digest_null), 0, SW_TYPE_HMAC },
  4139. + { cbc(cipher_null), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4140. + { "deflate", 0, SW_TYPE_COMP },
  4141. + { hmac(sha256), 0, SW_TYPE_HMAC },
  4142. + { hmac(sha384), 0, SW_TYPE_HMAC },
  4143. + { hmac(sha512), 0, SW_TYPE_HMAC },
  4144. + { cbc(camellia), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
  4145. + { "sha256", 0, SW_TYPE_HASH },
  4146. + { "sha384", 0, SW_TYPE_HASH },
  4147. + { "sha512", 0, SW_TYPE_HASH },
  4148. + { "ripemd160", 0, SW_TYPE_HASH },
  4149. +};
  4150. +
  4151. +int32_t swcr_id = -1;
  4152. +module_param(swcr_id, int, 0444);
  4153. +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
  4154. +
  4155. +int swcr_fail_if_compression_grows = 1;
  4156. +module_param(swcr_fail_if_compression_grows, int, 0644);
  4157. +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
  4158. + "Treat compression that results in more data as a failure");
  4159. +
  4160. +static struct swcr_data **swcr_sessions = NULL;
  4161. +static u_int32_t swcr_sesnum = 0;
  4162. +
  4163. +static int swcr_process(device_t, struct cryptop *, int);
  4164. +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
  4165. +static int swcr_freesession(device_t, u_int64_t);
  4166. +
  4167. +static device_method_t swcr_methods = {
  4168. + /* crypto device methods */
  4169. + DEVMETHOD(cryptodev_newsession, swcr_newsession),
  4170. + DEVMETHOD(cryptodev_freesession,swcr_freesession),
  4171. + DEVMETHOD(cryptodev_process, swcr_process),
  4172. +};
  4173. +
  4174. +#define debug swcr_debug
  4175. +int swcr_debug = 0;
  4176. +module_param(swcr_debug, int, 0644);
  4177. +MODULE_PARM_DESC(swcr_debug, "Enable debug");
  4178. +
  4179. +/*
  4180. + * Generate a new software session.
  4181. + */
  4182. +static int
  4183. +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  4184. +{
  4185. + struct swcr_data **swd;
  4186. + u_int32_t i;
  4187. + int error;
  4188. + char *algo;
  4189. + int mode, sw_type;
  4190. +
  4191. + dprintk("%s()\n", __FUNCTION__);
  4192. + if (sid == NULL || cri == NULL) {
  4193. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  4194. + return EINVAL;
  4195. + }
  4196. +
  4197. + if (swcr_sessions) {
  4198. + for (i = 1; i < swcr_sesnum; i++)
  4199. + if (swcr_sessions[i] == NULL)
  4200. + break;
  4201. + } else
  4202. + i = 1; /* NB: to silence compiler warning */
  4203. +
  4204. + if (swcr_sessions == NULL || i == swcr_sesnum) {
  4205. + if (swcr_sessions == NULL) {
  4206. + i = 1; /* We leave swcr_sessions[0] empty */
  4207. + swcr_sesnum = CRYPTO_SW_SESSIONS;
  4208. + } else
  4209. + swcr_sesnum *= 2;
  4210. +
  4211. + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
  4212. + if (swd == NULL) {
  4213. + /* Reset session number */
  4214. + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  4215. + swcr_sesnum = 0;
  4216. + else
  4217. + swcr_sesnum /= 2;
  4218. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  4219. + return ENOBUFS;
  4220. + }
  4221. + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
  4222. +
  4223. + /* Copy existing sessions */
  4224. + if (swcr_sessions) {
  4225. + memcpy(swd, swcr_sessions,
  4226. + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  4227. + kfree(swcr_sessions);
  4228. + }
  4229. +
  4230. + swcr_sessions = swd;
  4231. + }
  4232. +
  4233. + swd = &swcr_sessions[i];
  4234. + *sid = i;
  4235. +
  4236. + while (cri) {
  4237. + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
  4238. + SLAB_ATOMIC);
  4239. + if (*swd == NULL) {
  4240. + swcr_freesession(NULL, i);
  4241. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  4242. + return ENOBUFS;
  4243. + }
  4244. + memset(*swd, 0, sizeof(struct swcr_data));
  4245. +
  4246. + if (cri->cri_alg > CRYPTO_ALGORITHM_MAX) {
  4247. + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
  4248. + swcr_freesession(NULL, i);
  4249. + return EINVAL;
  4250. + }
  4251. +
  4252. + algo = crypto_details[cri->cri_alg].alg_name;
  4253. + if (!algo || !*algo) {
  4254. + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
  4255. + swcr_freesession(NULL, i);
  4256. + return EINVAL;
  4257. + }
  4258. +
  4259. + mode = crypto_details[cri->cri_alg].mode;
  4260. + sw_type = crypto_details[cri->cri_alg].sw_type;
  4261. +
  4262. + /* Algorithm specific configuration */
  4263. + switch (cri->cri_alg) {
  4264. + case CRYPTO_NULL_CBC:
  4265. + cri->cri_klen = 0; /* make it work with crypto API */
  4266. + break;
  4267. + default:
  4268. + break;
  4269. + }
  4270. +
  4271. + if (sw_type == SW_TYPE_BLKCIPHER) {
  4272. + dprintk("%s crypto_alloc_blkcipher(%s, 0x%x)\n", __FUNCTION__,
  4273. + algo, mode);
  4274. +
  4275. + (*swd)->sw_tfm = crypto_blkcipher_tfm(
  4276. + crypto_alloc_blkcipher(algo, 0,
  4277. + CRYPTO_ALG_ASYNC));
  4278. + if (!(*swd)->sw_tfm) {
  4279. + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s,0x%x)\n",
  4280. + algo,mode);
  4281. + swcr_freesession(NULL, i);
  4282. + return EINVAL;
  4283. + }
  4284. +
  4285. + if (debug) {
  4286. + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
  4287. + __FUNCTION__,cri->cri_klen,(cri->cri_klen + 7)/8);
  4288. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  4289. + {
  4290. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",cri->cri_key[i]);
  4291. + }
  4292. + dprintk("\n");
  4293. + }
  4294. + error = crypto_blkcipher_setkey(
  4295. + crypto_blkcipher_cast((*swd)->sw_tfm), cri->cri_key,
  4296. + (cri->cri_klen + 7) / 8);
  4297. + if (error) {
  4298. + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
  4299. + (*swd)->sw_tfm->crt_flags);
  4300. + swcr_freesession(NULL, i);
  4301. + return error;
  4302. + }
  4303. + } else if (sw_type == SW_TYPE_HMAC || sw_type == SW_TYPE_HASH) {
  4304. + dprintk("%s crypto_alloc_hash(%s, 0x%x)\n", __FUNCTION__,
  4305. + algo, mode);
  4306. +
  4307. + (*swd)->sw_tfm = crypto_hash_tfm(
  4308. + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
  4309. +
  4310. + if (!(*swd)->sw_tfm) {
  4311. + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
  4312. + algo, mode);
  4313. + swcr_freesession(NULL, i);
  4314. + return EINVAL;
  4315. + }
  4316. +
  4317. + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
  4318. + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
  4319. + SLAB_ATOMIC);
  4320. + if ((*swd)->u.hmac.sw_key == NULL) {
  4321. + swcr_freesession(NULL, i);
  4322. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  4323. + return ENOBUFS;
  4324. + }
  4325. + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
  4326. + if (cri->cri_mlen) {
  4327. + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
  4328. + } else {
  4329. + (*swd)->u.hmac.sw_mlen =
  4330. + crypto_hash_digestsize(
  4331. + crypto_hash_cast((*swd)->sw_tfm));
  4332. + }
  4333. + } else if (sw_type == SW_TYPE_COMP) {
  4334. + (*swd)->sw_tfm = crypto_comp_tfm(
  4335. + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
  4336. + if (!(*swd)->sw_tfm) {
  4337. + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
  4338. + algo, mode);
  4339. + swcr_freesession(NULL, i);
  4340. + return EINVAL;
  4341. + }
  4342. + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
  4343. + if ((*swd)->u.sw_comp_buf == NULL) {
  4344. + swcr_freesession(NULL, i);
  4345. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  4346. + return ENOBUFS;
  4347. + }
  4348. + } else {
  4349. + printk("cryptosoft: Unhandled sw_type %d\n", sw_type);
  4350. + swcr_freesession(NULL, i);
  4351. + return EINVAL;
  4352. + }
  4353. +
  4354. + (*swd)->sw_alg = cri->cri_alg;
  4355. + (*swd)->sw_type = sw_type;
  4356. +
  4357. + cri = cri->cri_next;
  4358. + swd = &((*swd)->sw_next);
  4359. + }
  4360. + return 0;
  4361. +}
  4362. +
  4363. +/*
  4364. + * Free a session.
  4365. + */
  4366. +static int
  4367. +swcr_freesession(device_t dev, u_int64_t tid)
  4368. +{
  4369. + struct swcr_data *swd;
  4370. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  4371. +
  4372. + dprintk("%s()\n", __FUNCTION__);
  4373. + if (sid > swcr_sesnum || swcr_sessions == NULL ||
  4374. + swcr_sessions[sid] == NULL) {
  4375. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4376. + return(EINVAL);
  4377. + }
  4378. +
  4379. + /* Silently accept and return */
  4380. + if (sid == 0)
  4381. + return(0);
  4382. +
  4383. + while ((swd = swcr_sessions[sid]) != NULL) {
  4384. + swcr_sessions[sid] = swd->sw_next;
  4385. + if (swd->sw_tfm)
  4386. + crypto_free_tfm(swd->sw_tfm);
  4387. + if (swd->sw_type == SW_TYPE_COMP) {
  4388. + if (swd->u.sw_comp_buf)
  4389. + kfree(swd->u.sw_comp_buf);
  4390. + } else {
  4391. + if (swd->u.hmac.sw_key)
  4392. + kfree(swd->u.hmac.sw_key);
  4393. + }
  4394. + kfree(swd);
  4395. + }
  4396. + return 0;
  4397. +}
  4398. +
  4399. +/*
  4400. + * Process a software request.
  4401. + */
  4402. +static int
  4403. +swcr_process(device_t dev, struct cryptop *crp, int hint)
  4404. +{
  4405. + struct cryptodesc *crd;
  4406. + struct swcr_data *sw;
  4407. + u_int32_t lid;
  4408. +#define SCATTERLIST_MAX 16
  4409. + struct scatterlist sg[SCATTERLIST_MAX];
  4410. + int sg_num, sg_len, skip;
  4411. + struct sk_buff *skb = NULL;
  4412. + struct uio *uiop = NULL;
  4413. +
  4414. + dprintk("%s()\n", __FUNCTION__);
  4415. + /* Sanity check */
  4416. + if (crp == NULL) {
  4417. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4418. + return EINVAL;
  4419. + }
  4420. +
  4421. + crp->crp_etype = 0;
  4422. +
  4423. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  4424. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4425. + crp->crp_etype = EINVAL;
  4426. + goto done;
  4427. + }
  4428. +
  4429. + lid = crp->crp_sid & 0xffffffff;
  4430. + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
  4431. + swcr_sessions[lid] == NULL) {
  4432. + crp->crp_etype = ENOENT;
  4433. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  4434. + goto done;
  4435. + }
  4436. +
  4437. + /*
  4438. + * do some error checking outside of the loop for SKB and IOV processing
  4439. + * this leaves us with valid skb or uiop pointers for later
  4440. + */
  4441. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  4442. + skb = (struct sk_buff *) crp->crp_buf;
  4443. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  4444. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  4445. + skb_shinfo(skb)->nr_frags);
  4446. + goto done;
  4447. + }
  4448. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  4449. + uiop = (struct uio *) crp->crp_buf;
  4450. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  4451. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  4452. + uiop->uio_iovcnt);
  4453. + goto done;
  4454. + }
  4455. + }
  4456. +
  4457. + /* Go through crypto descriptors, processing as we go */
  4458. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  4459. + /*
  4460. + * Find the crypto context.
  4461. + *
  4462. + * XXX Note that the logic here prevents us from having
  4463. + * XXX the same algorithm multiple times in a session
  4464. + * XXX (or rather, we can but it won't give us the right
  4465. + * XXX results). To do that, we'd need some way of differentiating
  4466. + * XXX between the various instances of an algorithm (so we can
  4467. + * XXX locate the correct crypto context).
  4468. + */
  4469. + for (sw = swcr_sessions[lid]; sw && sw->sw_alg != crd->crd_alg;
  4470. + sw = sw->sw_next)
  4471. + ;
  4472. +
  4473. + /* No such context ? */
  4474. + if (sw == NULL) {
  4475. + crp->crp_etype = EINVAL;
  4476. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4477. + goto done;
  4478. + }
  4479. +
  4480. + skip = crd->crd_skip;
  4481. +
  4482. + /*
  4483. + * setup the SG list skip from the start of the buffer
  4484. + */
  4485. + memset(sg, 0, sizeof(sg));
  4486. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  4487. + int i, len;
  4488. +
  4489. + sg_num = 0;
  4490. + sg_len = 0;
  4491. +
  4492. + if (skip < skb_headlen(skb)) {
  4493. + len = skb_headlen(skb) - skip;
  4494. + if (len + sg_len > crd->crd_len)
  4495. + len = crd->crd_len - sg_len;
  4496. + sg_set_page(&sg[sg_num],
  4497. + virt_to_page(skb->data + skip), len,
  4498. + offset_in_page(skb->data + skip));
  4499. + sg_len += len;
  4500. + sg_num++;
  4501. + skip = 0;
  4502. + } else
  4503. + skip -= skb_headlen(skb);
  4504. +
  4505. + for (i = 0; sg_len < crd->crd_len &&
  4506. + i < skb_shinfo(skb)->nr_frags &&
  4507. + sg_num < SCATTERLIST_MAX; i++) {
  4508. + if (skip < skb_shinfo(skb)->frags[i].size) {
  4509. + len = skb_shinfo(skb)->frags[i].size - skip;
  4510. + if (len + sg_len > crd->crd_len)
  4511. + len = crd->crd_len - sg_len;
  4512. + sg_set_page(&sg[sg_num],
  4513. + skb_shinfo(skb)->frags[i].page,
  4514. + len,
  4515. + skb_shinfo(skb)->frags[i].page_offset + skip);
  4516. + sg_len += len;
  4517. + sg_num++;
  4518. + skip = 0;
  4519. + } else
  4520. + skip -= skb_shinfo(skb)->frags[i].size;
  4521. + }
  4522. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  4523. + int len;
  4524. +
  4525. + sg_len = 0;
  4526. + for (sg_num = 0; sg_len <= crd->crd_len &&
  4527. + sg_num < uiop->uio_iovcnt &&
  4528. + sg_num < SCATTERLIST_MAX; sg_num++) {
  4529. + if (skip <= uiop->uio_iov[sg_num].iov_len) {
  4530. + len = uiop->uio_iov[sg_num].iov_len - skip;
  4531. + if (len + sg_len > crd->crd_len)
  4532. + len = crd->crd_len - sg_len;
  4533. + sg_set_page(&sg[sg_num],
  4534. + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
  4535. + len,
  4536. + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
  4537. + sg_len += len;
  4538. + skip = 0;
  4539. + } else
  4540. + skip -= uiop->uio_iov[sg_num].iov_len;
  4541. + }
  4542. + } else {
  4543. + sg_len = (crp->crp_ilen - skip);
  4544. + if (sg_len > crd->crd_len)
  4545. + sg_len = crd->crd_len;
  4546. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip),
  4547. + sg_len, offset_in_page(crp->crp_buf + skip));
  4548. + sg_num = 1;
  4549. + }
  4550. +
  4551. +
  4552. + switch (sw->sw_type) {
  4553. + case SW_TYPE_BLKCIPHER: {
  4554. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  4555. + unsigned char *ivp = iv;
  4556. + int ivsize =
  4557. + crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
  4558. + struct blkcipher_desc desc;
  4559. +
  4560. + if (sg_len < crypto_blkcipher_blocksize(
  4561. + crypto_blkcipher_cast(sw->sw_tfm))) {
  4562. + crp->crp_etype = EINVAL;
  4563. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  4564. + sg_len, crypto_blkcipher_blocksize(
  4565. + crypto_blkcipher_cast(sw->sw_tfm)));
  4566. + goto done;
  4567. + }
  4568. +
  4569. + if (ivsize > sizeof(iv)) {
  4570. + crp->crp_etype = EINVAL;
  4571. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4572. + goto done;
  4573. + }
  4574. +
  4575. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  4576. + int i, error;
  4577. +
  4578. + if (debug) {
  4579. + dprintk("%s key:", __FUNCTION__);
  4580. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  4581. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  4582. + crd->crd_key[i]);
  4583. + dprintk("\n");
  4584. + }
  4585. + error = crypto_blkcipher_setkey(
  4586. + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
  4587. + (crd->crd_klen + 7) / 8);
  4588. + if (error) {
  4589. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  4590. + error, sw->sw_tfm->crt_flags);
  4591. + crp->crp_etype = -error;
  4592. + }
  4593. + }
  4594. +
  4595. + memset(&desc, 0, sizeof(desc));
  4596. + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
  4597. +
  4598. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  4599. +
  4600. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  4601. + ivp = crd->crd_iv;
  4602. + } else {
  4603. + get_random_bytes(ivp, ivsize);
  4604. + }
  4605. + /*
  4606. + * do we have to copy the IV back to the buffer ?
  4607. + */
  4608. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  4609. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  4610. + crd->crd_inject, ivsize, (caddr_t)ivp);
  4611. + }
  4612. + desc.info = ivp;
  4613. + crypto_blkcipher_encrypt_iv(&desc, sg, sg, sg_len);
  4614. +
  4615. + } else { /*decrypt */
  4616. +
  4617. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  4618. + ivp = crd->crd_iv;
  4619. + } else {
  4620. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  4621. + crd->crd_inject, ivsize, (caddr_t)ivp);
  4622. + }
  4623. + desc.info = ivp;
  4624. + crypto_blkcipher_decrypt_iv(&desc, sg, sg, sg_len);
  4625. + }
  4626. + } break;
  4627. + case SW_TYPE_HMAC:
  4628. + case SW_TYPE_HASH:
  4629. + {
  4630. + char result[HASH_MAX_LEN];
  4631. + struct hash_desc desc;
  4632. +
  4633. + /* check we have room for the result */
  4634. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  4635. + dprintk(
  4636. + "cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d digestsize=%d\n",
  4637. + crp->crp_ilen, crd->crd_skip + sg_len, crd->crd_inject,
  4638. + sw->u.hmac.sw_mlen);
  4639. + crp->crp_etype = EINVAL;
  4640. + goto done;
  4641. + }
  4642. +
  4643. + memset(&desc, 0, sizeof(desc));
  4644. + desc.tfm = crypto_hash_cast(sw->sw_tfm);
  4645. +
  4646. + memset(result, 0, sizeof(result));
  4647. +
  4648. + if (sw->sw_type == SW_TYPE_HMAC) {
  4649. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  4650. + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
  4651. + sg, sg_num, result);
  4652. +#else
  4653. + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
  4654. + sw->u.hmac.sw_klen);
  4655. + crypto_hash_digest(&desc, sg, sg_len, result);
  4656. +#endif /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  4657. +
  4658. + } else { /* SW_TYPE_HASH */
  4659. + crypto_hash_digest(&desc, sg, sg_len, result);
  4660. + }
  4661. +
  4662. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  4663. + crd->crd_inject, sw->u.hmac.sw_mlen, result);
  4664. + }
  4665. + break;
  4666. +
  4667. + case SW_TYPE_COMP: {
  4668. + void *ibuf = NULL;
  4669. + void *obuf = sw->u.sw_comp_buf;
  4670. + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
  4671. + int ret = 0;
  4672. +
  4673. + /*
  4674. + * we need to use an additional copy if there is more than one
  4675. + * input chunk since the kernel comp routines do not handle
  4676. + * SG yet. Otherwise we just use the input buffer as is.
  4677. + * Rather than allocate another buffer we just split the tmp
  4678. + * buffer we already have.
  4679. + * Perhaps we should just use zlib directly ?
  4680. + */
  4681. + if (sg_num > 1) {
  4682. + int blk;
  4683. +
  4684. + ibuf = obuf;
  4685. + for (blk = 0; blk < sg_num; blk++) {
  4686. + memcpy(obuf, sg_virt(&sg[blk]),
  4687. + sg[blk].length);
  4688. + obuf += sg[blk].length;
  4689. + }
  4690. + olen -= sg_len;
  4691. + } else
  4692. + ibuf = sg_virt(&sg[0]);
  4693. +
  4694. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
  4695. + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
  4696. + ibuf, ilen, obuf, &olen);
  4697. + if (!ret && olen > crd->crd_len) {
  4698. + dprintk("cryptosoft: ERANGE compress %d into %d\n",
  4699. + crd->crd_len, olen);
  4700. + if (swcr_fail_if_compression_grows)
  4701. + ret = ERANGE;
  4702. + }
  4703. + } else { /* decompress */
  4704. + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
  4705. + ibuf, ilen, obuf, &olen);
  4706. + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
  4707. + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
  4708. + "space for %d,at offset %d\n",
  4709. + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
  4710. + ret = ETOOSMALL;
  4711. + }
  4712. + }
  4713. + if (ret)
  4714. + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
  4715. +
  4716. + /*
  4717. + * on success copy result back,
  4718. + * linux crpyto API returns -errno, we need to fix that
  4719. + */
  4720. + crp->crp_etype = ret < 0 ? -ret : ret;
  4721. + if (ret == 0) {
  4722. + /* copy back the result and return it's size */
  4723. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  4724. + crd->crd_inject, olen, obuf);
  4725. + crp->crp_olen = olen;
  4726. + }
  4727. +
  4728. +
  4729. + } break;
  4730. +
  4731. + default:
  4732. + /* Unknown/unsupported algorithm */
  4733. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  4734. + crp->crp_etype = EINVAL;
  4735. + goto done;
  4736. + }
  4737. + }
  4738. +
  4739. +done:
  4740. + crypto_done(crp);
  4741. + return 0;
  4742. +}
  4743. +
  4744. +static int
  4745. +cryptosoft_init(void)
  4746. +{
  4747. + int i, sw_type, mode;
  4748. + char *algo;
  4749. +
  4750. + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
  4751. +
  4752. + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
  4753. +
  4754. + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
  4755. + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
  4756. + if (swcr_id < 0) {
  4757. + printk("Software crypto device cannot initialize!");
  4758. + return -ENODEV;
  4759. + }
  4760. +
  4761. +#define REGISTER(alg) \
  4762. + crypto_register(swcr_id, alg, 0,0);
  4763. +
  4764. + for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; ++i)
  4765. + {
  4766. +
  4767. + algo = crypto_details[i].alg_name;
  4768. + if (!algo || !*algo)
  4769. + {
  4770. + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
  4771. + continue;
  4772. + }
  4773. +
  4774. + mode = crypto_details[i].mode;
  4775. + sw_type = crypto_details[i].sw_type;
  4776. +
  4777. + switch (sw_type)
  4778. + {
  4779. + case SW_TYPE_CIPHER:
  4780. + if (crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC))
  4781. + {
  4782. + REGISTER(i);
  4783. + }
  4784. + else
  4785. + {
  4786. + dprintk("%s:CIPHER algorithm %d:'%s' not supported\n",
  4787. + __FUNCTION__, i, algo);
  4788. + }
  4789. + break;
  4790. + case SW_TYPE_HMAC:
  4791. + if (crypto_has_hash(algo, 0, CRYPTO_ALG_ASYNC))
  4792. + {
  4793. + REGISTER(i);
  4794. + }
  4795. + else
  4796. + {
  4797. + dprintk("%s:HMAC algorithm %d:'%s' not supported\n",
  4798. + __FUNCTION__, i, algo);
  4799. + }
  4800. + break;
  4801. + case SW_TYPE_HASH:
  4802. + if (crypto_has_hash(algo, 0, CRYPTO_ALG_ASYNC))
  4803. + {
  4804. + REGISTER(i);
  4805. + }
  4806. + else
  4807. + {
  4808. + dprintk("%s:HASH algorithm %d:'%s' not supported\n",
  4809. + __FUNCTION__, i, algo);
  4810. + }
  4811. + break;
  4812. + case SW_TYPE_COMP:
  4813. + if (crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC))
  4814. + {
  4815. + REGISTER(i);
  4816. + }
  4817. + else
  4818. + {
  4819. + dprintk("%s:COMP algorithm %d:'%s' not supported\n",
  4820. + __FUNCTION__, i, algo);
  4821. + }
  4822. + break;
  4823. + case SW_TYPE_BLKCIPHER:
  4824. + if (crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC))
  4825. + {
  4826. + REGISTER(i);
  4827. + }
  4828. + else
  4829. + {
  4830. + dprintk("%s:BLKCIPHER algorithm %d:'%s' not supported\n",
  4831. + __FUNCTION__, i, algo);
  4832. + }
  4833. + break;
  4834. + default:
  4835. + dprintk(
  4836. + "%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
  4837. + __FUNCTION__, sw_type, i, algo);
  4838. + break;
  4839. + }
  4840. + }
  4841. +
  4842. + return(0);
  4843. +}
  4844. +
  4845. +static void
  4846. +cryptosoft_exit(void)
  4847. +{
  4848. + dprintk("%s()\n", __FUNCTION__);
  4849. + crypto_unregister_all(swcr_id);
  4850. + swcr_id = -1;
  4851. +}
  4852. +
  4853. +module_init(cryptosoft_init);
  4854. +module_exit(cryptosoft_exit);
  4855. +
  4856. +MODULE_LICENSE("Dual BSD/GPL");
  4857. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  4858. +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
  4859. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ep80579/Makefile linux-2.6.29.1/crypto/ocf/ep80579/Makefile
  4860. --- linux-2.6.29.1.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
  4861. +++ linux-2.6.29.1/crypto/ocf/ep80579/Makefile 2009-04-20 20:01:21.468554715 +0200
  4862. @@ -0,0 +1,107 @@
  4863. +#########################################################################
  4864. +#
  4865. +# Targets supported
  4866. +# all - builds everything and installs
  4867. +# install - identical to all
  4868. +# depend - build dependencies
  4869. +# clean - clears derived objects except the .depend files
  4870. +# distclean- clears all derived objects and the .depend file
  4871. +#
  4872. +# @par
  4873. +# This file is provided under a dual BSD/GPLv2 license. When using or
  4874. +# redistributing this file, you may do so under either license.
  4875. +#
  4876. +# GPL LICENSE SUMMARY
  4877. +#
  4878. +# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  4879. +#
  4880. +# This program is free software; you can redistribute it and/or modify
  4881. +# it under the terms of version 2 of the GNU General Public License as
  4882. +# published by the Free Software Foundation.
  4883. +#
  4884. +# This program is distributed in the hope that it will be useful, but
  4885. +# WITHOUT ANY WARRANTY; without even the implied warranty of
  4886. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  4887. +# General Public License for more details.
  4888. +#
  4889. +# You should have received a copy of the GNU General Public License
  4890. +# along with this program; if not, write to the Free Software
  4891. +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  4892. +# The full GNU General Public License is included in this distribution
  4893. +# in the file called LICENSE.GPL.
  4894. +#
  4895. +# Contact Information:
  4896. +# Intel Corporation
  4897. +#
  4898. +# BSD LICENSE
  4899. +#
  4900. +# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  4901. +# All rights reserved.
  4902. +#
  4903. +# Redistribution and use in source and binary forms, with or without
  4904. +# modification, are permitted provided that the following conditions
  4905. +# are met:
  4906. +#
  4907. +# * Redistributions of source code must retain the above copyright
  4908. +# notice, this list of conditions and the following disclaimer.
  4909. +# * Redistributions in binary form must reproduce the above copyright
  4910. +# notice, this list of conditions and the following disclaimer in
  4911. +# the documentation and/or other materials provided with the
  4912. +# distribution.
  4913. +# * Neither the name of Intel Corporation nor the names of its
  4914. +# contributors may be used to endorse or promote products derived
  4915. +# from this software without specific prior written permission.
  4916. +#
  4917. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4918. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  4919. +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  4920. +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  4921. +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  4922. +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  4923. +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  4924. +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  4925. +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  4926. +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  4927. +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  4928. +#
  4929. +#
  4930. +# version: Security.L.1.0.130
  4931. +############################################################################
  4932. +
  4933. +
  4934. +####################Common variables and definitions########################
  4935. +
  4936. +# Ensure The ENV_DIR environmental var is defined.
  4937. +ifndef ICP_ENV_DIR
  4938. +$(error ICP_ENV_DIR is undefined. Please set the path to your environment makefile \
  4939. + "-> setenv ICP_ENV_DIR <path>")
  4940. +endif
  4941. +
  4942. +#Add your project environment Makefile
  4943. +include $(ICP_ENV_DIR)/environment.mk
  4944. +
  4945. +#include the makefile with all the default and common Make variable definitions
  4946. +include $(ICP_BUILDSYSTEM_PATH)/build_files/common.mk
  4947. +
  4948. +#Add the name for the executable, Library or Module output definitions
  4949. +OUTPUT_NAME= icp_ocf
  4950. +
  4951. +# List of Source Files to be compiled
  4952. +SOURCES= icp_common.c icp_sym.c icp_asym.c
  4953. +
  4954. +#common includes between all supported OSes
  4955. +INCLUDES= -I $(ICP_API_DIR) -I$(ICP_LAC_API) \
  4956. +-I$(ICP_OCF_SRC_DIR)
  4957. +
  4958. +# The location of the os level makefile needs to be changed.
  4959. +include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk
  4960. +
  4961. +# On the line directly below list the outputs you wish to build for,
  4962. +# e.g "lib_static lib_shared exe module" as show below
  4963. +install: module
  4964. +
  4965. +###################Include rules makefiles########################
  4966. +include $(ICP_BUILDSYSTEM_PATH)/build_files/rules.mk
  4967. +###################End of Rules inclusion#########################
  4968. +
  4969. +
  4970. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.29.1/crypto/ocf/ep80579/icp_asym.c
  4971. --- linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
  4972. +++ linux-2.6.29.1/crypto/ocf/ep80579/icp_asym.c 2009-04-20 20:01:21.428551297 +0200
  4973. @@ -0,0 +1,1375 @@
  4974. +/***************************************************************************
  4975. + *
  4976. + * This file is provided under a dual BSD/GPLv2 license. When using or
  4977. + * redistributing this file, you may do so under either license.
  4978. + *
  4979. + * GPL LICENSE SUMMARY
  4980. + *
  4981. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  4982. + *
  4983. + * This program is free software; you can redistribute it and/or modify
  4984. + * it under the terms of version 2 of the GNU General Public License as
  4985. + * published by the Free Software Foundation.
  4986. + *
  4987. + * This program is distributed in the hope that it will be useful, but
  4988. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  4989. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  4990. + * General Public License for more details.
  4991. + *
  4992. + * You should have received a copy of the GNU General Public License
  4993. + * along with this program; if not, write to the Free Software
  4994. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  4995. + * The full GNU General Public License is included in this distribution
  4996. + * in the file called LICENSE.GPL.
  4997. + *
  4998. + * Contact Information:
  4999. + * Intel Corporation
  5000. + *
  5001. + * BSD LICENSE
  5002. + *
  5003. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  5004. + * All rights reserved.
  5005. + *
  5006. + * Redistribution and use in source and binary forms, with or without
  5007. + * modification, are permitted provided that the following conditions
  5008. + * are met:
  5009. + *
  5010. + * * Redistributions of source code must retain the above copyright
  5011. + * notice, this list of conditions and the following disclaimer.
  5012. + * * Redistributions in binary form must reproduce the above copyright
  5013. + * notice, this list of conditions and the following disclaimer in
  5014. + * the documentation and/or other materials provided with the
  5015. + * distribution.
  5016. + * * Neither the name of Intel Corporation nor the names of its
  5017. + * contributors may be used to endorse or promote products derived
  5018. + * from this software without specific prior written permission.
  5019. + *
  5020. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  5021. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5022. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  5023. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  5024. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  5025. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  5026. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  5027. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  5028. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  5029. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  5030. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  5031. + *
  5032. + *
  5033. + * version: Security.L.1.0.130
  5034. + *
  5035. + ***************************************************************************/
  5036. +
  5037. +#include "icp_ocf.h"
  5038. +
  5039. +/*The following define values (containing the word 'INDEX') are used to find
  5040. +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
  5041. +These values were found through analysis of the OCF OpenSSL patch. If the
  5042. +calling program uses different input buffer positions, these defines will have
  5043. +to be changed.*/
  5044. +
  5045. +/*DIFFIE HELLMAN buffer index values*/
  5046. +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
  5047. +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
  5048. +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
  5049. +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
  5050. +
  5051. +/*MOD EXP buffer index values*/
  5052. +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
  5053. +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
  5054. +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
  5055. +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
  5056. +
  5057. +#define SINGLE_BYTE_VALUE (4)
  5058. +
  5059. +/*MOD EXP CRT buffer index values*/
  5060. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
  5061. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
  5062. +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
  5063. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
  5064. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
  5065. +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
  5066. +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
  5067. +
  5068. +/*DSA sign buffer index values*/
  5069. +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
  5070. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
  5071. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
  5072. +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
  5073. +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
  5074. +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
  5075. +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
  5076. +
  5077. +/*DSA verify buffer index values*/
  5078. +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
  5079. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
  5080. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
  5081. +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
  5082. +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
  5083. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
  5084. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
  5085. +
  5086. +/*DSA sign prime Q vs random number K size check values*/
  5087. +#define DONT_RUN_LESS_THAN_CHECK (0)
  5088. +#define FAIL_A_IS_GREATER_THAN_B (1)
  5089. +#define FAIL_A_IS_EQUAL_TO_B (1)
  5090. +#define SUCCESS_A_IS_LESS_THAN_B (0)
  5091. +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
  5092. +
  5093. +/* We need to set a cryptokp success value just in case it is set or allocated
  5094. + and not set to zero outside of this module */
  5095. +#define CRYPTO_OP_SUCCESS (0)
  5096. +
  5097. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
  5098. +
  5099. +static int icp_ocfDrvModExp(struct cryptkop *krp);
  5100. +
  5101. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
  5102. +
  5103. +static int
  5104. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
  5105. +
  5106. +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
  5107. +
  5108. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
  5109. +
  5110. +static void
  5111. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  5112. + CpaStatus status,
  5113. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
  5114. +
  5115. +static void
  5116. +icp_ocfDrvModExpCallBack(void *callbackTag,
  5117. + CpaStatus status,
  5118. + void *pOpData, CpaFlatBuffer * pResult);
  5119. +
  5120. +static void
  5121. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  5122. + CpaStatus status,
  5123. + void *pOpData, CpaFlatBuffer * pOutputData);
  5124. +
  5125. +static void
  5126. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  5127. + CpaStatus status,
  5128. + void *pOpData, CpaBoolean verifyStatus);
  5129. +
  5130. +static void
  5131. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  5132. + CpaStatus status,
  5133. + void *pOpData,
  5134. + CpaBoolean protocolStatus,
  5135. + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
  5136. +
  5137. +/* Name : icp_ocfDrvPkeProcess
  5138. + *
  5139. + * Description : This function will choose which PKE process to follow
  5140. + * based on the input arguments
  5141. + */
  5142. +int icp_ocfDrvPkeProcess(device_t dev, struct cryptkop *krp, int hint)
  5143. +{
  5144. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5145. +
  5146. + if (NULL == krp) {
  5147. + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
  5148. + __FUNCTION__, krp);
  5149. + return EINVAL;
  5150. + }
  5151. +
  5152. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  5153. + krp->krp_status = ECANCELED;
  5154. + return ECANCELED;
  5155. + }
  5156. +
  5157. + switch (krp->krp_op) {
  5158. + case CRK_DH_COMPUTE_KEY:
  5159. + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
  5160. + lacStatus = icp_ocfDrvDHComputeKey(krp);
  5161. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5162. + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
  5163. + "(%d).\n", __FUNCTION__, lacStatus);
  5164. + krp->krp_status = ECANCELED;
  5165. + return ECANCELED;
  5166. + }
  5167. +
  5168. + break;
  5169. +
  5170. + case CRK_MOD_EXP:
  5171. + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
  5172. + lacStatus = icp_ocfDrvModExp(krp);
  5173. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5174. + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
  5175. + __FUNCTION__, lacStatus);
  5176. + krp->krp_status = ECANCELED;
  5177. + return ECANCELED;
  5178. + }
  5179. +
  5180. + break;
  5181. +
  5182. + case CRK_MOD_EXP_CRT:
  5183. + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
  5184. + lacStatus = icp_ocfDrvModExpCRT(krp);
  5185. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5186. + EPRINTK("%s(): icp_ocfDrvModExpCRT "
  5187. + "failed (%d).\n", __FUNCTION__, lacStatus);
  5188. + krp->krp_status = ECANCELED;
  5189. + return ECANCELED;
  5190. + }
  5191. +
  5192. + break;
  5193. +
  5194. + case CRK_DSA_SIGN:
  5195. + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
  5196. + lacStatus = icp_ocfDrvDsaSign(krp);
  5197. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5198. + EPRINTK("%s(): icp_ocfDrvDsaSign "
  5199. + "failed (%d).\n", __FUNCTION__, lacStatus);
  5200. + krp->krp_status = ECANCELED;
  5201. + return ECANCELED;
  5202. + }
  5203. +
  5204. + break;
  5205. +
  5206. + case CRK_DSA_VERIFY:
  5207. + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
  5208. + lacStatus = icp_ocfDrvDsaVerify(krp);
  5209. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5210. + EPRINTK("%s(): icp_ocfDrvDsaVerify "
  5211. + "failed (%d).\n", __FUNCTION__, lacStatus);
  5212. + krp->krp_status = ECANCELED;
  5213. + return ECANCELED;
  5214. + }
  5215. +
  5216. + break;
  5217. +
  5218. + default:
  5219. + EPRINTK("%s(): Asymettric function not "
  5220. + "supported (%d).\n", __FUNCTION__, krp->krp_op);
  5221. + krp->krp_status = EOPNOTSUPP;
  5222. + return EOPNOTSUPP;
  5223. + }
  5224. +
  5225. + return ICP_OCF_DRV_STATUS_SUCCESS;
  5226. +}
  5227. +
  5228. +/* Name : icp_ocfDrvSwapBytes
  5229. + *
  5230. + * Description : This function is used to swap the byte order of a buffer.
  5231. + * It has been seen that in general we are passed little endian byte order
  5232. + * buffers, but LAC only accepts big endian byte order buffers.
  5233. + */
  5234. +static void inline
  5235. +icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
  5236. +{
  5237. +
  5238. + int i;
  5239. + u_int8_t *end_ptr;
  5240. + u_int8_t hold_val;
  5241. +
  5242. + end_ptr = num + (buff_len_bytes - 1);
  5243. + buff_len_bytes = buff_len_bytes >> 1;
  5244. + for (i = 0; i < buff_len_bytes; i++) {
  5245. + hold_val = *num;
  5246. + *num = *end_ptr;
  5247. + num++;
  5248. + *end_ptr = hold_val;
  5249. + end_ptr--;
  5250. + }
  5251. +}
  5252. +
  5253. +/* Name : icp_ocfDrvDHComputeKey
  5254. + *
  5255. + * Description : This function will map Diffie Hellman calls from OCF
  5256. + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
  5257. + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
  5258. + * break down to a modular exponentiation.
  5259. + */
  5260. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
  5261. +{
  5262. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5263. + void *callbackTag = NULL;
  5264. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  5265. + CpaFlatBuffer *pLocalOctetStringPV = NULL;
  5266. + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
  5267. +
  5268. + /* Input checks - check prime is a multiple of 8 bits to allow for
  5269. + allocation later */
  5270. + dh_prime_len_bits =
  5271. + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
  5272. +
  5273. + /* LAC can reject prime lengths based on prime key sizes, we just
  5274. + need to make sure we can allocate space for the base and
  5275. + exponent buffers correctly */
  5276. + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
  5277. + APRINTK("%s(): Warning Prime number buffer size is not a "
  5278. + "multiple of 8 bits\n", __FUNCTION__);
  5279. + }
  5280. +
  5281. + /* Result storage space should be the same size as the prime as this
  5282. + value can take up the same amount of storage space */
  5283. + if (dh_prime_len_bits !=
  5284. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  5285. + DPRINTK("%s(): Return Buffer must be the same size "
  5286. + "as the Prime buffer\n", __FUNCTION__);
  5287. + krp->krp_status = EINVAL;
  5288. + return EINVAL;
  5289. + }
  5290. + /* Switch to size in bytes */
  5291. + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
  5292. +
  5293. + callbackTag = krp;
  5294. +
  5295. + pPhase1OpData = kmem_cache_zalloc(drvDH_zone, GFP_KERNEL);
  5296. + if (NULL == pPhase1OpData) {
  5297. + APRINTK("%s():Failed to get memory for key gen data\n",
  5298. + __FUNCTION__);
  5299. + krp->krp_status = ENOMEM;
  5300. + return ENOMEM;
  5301. + }
  5302. +
  5303. + pLocalOctetStringPV = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5304. + if (NULL == pLocalOctetStringPV) {
  5305. + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
  5306. + __FUNCTION__);
  5307. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  5308. + krp->krp_status = ENOMEM;
  5309. + return ENOMEM;
  5310. + }
  5311. +
  5312. + /* Link parameters */
  5313. + pPhase1OpData->primeP.pData =
  5314. + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
  5315. +
  5316. + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
  5317. +
  5318. + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
  5319. +
  5320. + pPhase1OpData->baseG.pData =
  5321. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
  5322. +
  5323. + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
  5324. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
  5325. +
  5326. + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
  5327. + pPhase1OpData->baseG.dataLenInBytes);
  5328. +
  5329. + pPhase1OpData->privateValueX.pData =
  5330. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
  5331. +
  5332. + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
  5333. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
  5334. + crp_nbits);
  5335. +
  5336. + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
  5337. + pPhase1OpData->privateValueX.dataLenInBytes);
  5338. +
  5339. + /* Output parameters */
  5340. + pLocalOctetStringPV->pData =
  5341. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
  5342. +
  5343. + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
  5344. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
  5345. +
  5346. + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
  5347. + icp_ocfDrvDhP1CallBack,
  5348. + callbackTag, pPhase1OpData,
  5349. + pLocalOctetStringPV);
  5350. +
  5351. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5352. + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
  5353. + __FUNCTION__, lacStatus);
  5354. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  5355. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  5356. + }
  5357. +
  5358. + return lacStatus;
  5359. +}
  5360. +
  5361. +/* Name : icp_ocfDrvModExp
  5362. + *
  5363. + * Description : This function will map ordinary Modular Exponentiation calls
  5364. + * from OCF to the LAC API.
  5365. + *
  5366. + */
  5367. +static int icp_ocfDrvModExp(struct cryptkop *krp)
  5368. +{
  5369. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5370. + void *callbackTag = NULL;
  5371. + CpaCyLnModExpOpData *pModExpOpData = NULL;
  5372. + CpaFlatBuffer *pResult = NULL;
  5373. +
  5374. + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
  5375. + NUM_BITS_IN_BYTE) != 0) {
  5376. + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
  5377. + "multiple of 8 bits\n", __FUNCTION__,
  5378. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  5379. + crp_nbits);
  5380. + }
  5381. +
  5382. + /* Result storage space should be the same size as the prime as this
  5383. + value can take up the same amount of storage space */
  5384. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
  5385. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  5386. + APRINTK("%s(): Return Buffer size must be the same or"
  5387. + " greater than the Modulus buffer\n", __FUNCTION__);
  5388. + krp->krp_status = EINVAL;
  5389. + return EINVAL;
  5390. + }
  5391. +
  5392. + callbackTag = krp;
  5393. +
  5394. + pModExpOpData = kmem_cache_zalloc(drvLnModExp_zone, GFP_KERNEL);
  5395. + if (NULL == pModExpOpData) {
  5396. + APRINTK("%s():Failed to get memory for key gen data\n",
  5397. + __FUNCTION__);
  5398. + krp->krp_status = ENOMEM;
  5399. + return ENOMEM;
  5400. + }
  5401. +
  5402. + pResult = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5403. + if (NULL == pResult) {
  5404. + APRINTK("%s():Failed to get memory for ModExp result\n",
  5405. + __FUNCTION__);
  5406. + kmem_cache_free(drvLnModExp_zone, pModExpOpData);
  5407. + krp->krp_status = ENOMEM;
  5408. + return ENOMEM;
  5409. + }
  5410. +
  5411. + /* Link parameters */
  5412. + pModExpOpData->modulus.pData =
  5413. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
  5414. + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
  5415. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  5416. + crp_nbits);
  5417. +
  5418. + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
  5419. + pModExpOpData->modulus.dataLenInBytes);
  5420. +
  5421. + /*OCF patch to Openswan Pluto regularly sends the base value as 2
  5422. + bits in size. In this case, it has been found it is better to
  5423. + use the base size memory space as the input buffer (if the number
  5424. + is in bits is less than a byte, the number of bits is the input
  5425. + value) */
  5426. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits <
  5427. + NUM_BITS_IN_BYTE) {
  5428. + DPRINTK("%s : base is small (%d)\n", __FUNCTION__, krp->
  5429. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  5430. + pModExpOpData->base.dataLenInBytes = SINGLE_BYTE_VALUE;
  5431. + pModExpOpData->base.pData =
  5432. + (uint8_t *) & (krp->
  5433. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  5434. + crp_nbits);
  5435. + *((uint32_t *) pModExpOpData->base.pData) =
  5436. + htonl(*((uint32_t *) pModExpOpData->base.pData));
  5437. +
  5438. + } else {
  5439. +
  5440. + DPRINTK("%s : base is big (%d)\n", __FUNCTION__, krp->
  5441. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  5442. + pModExpOpData->base.pData =
  5443. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
  5444. + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
  5445. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  5446. + crp_nbits);
  5447. + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
  5448. + pModExpOpData->base.dataLenInBytes);
  5449. + }
  5450. +
  5451. + pModExpOpData->exponent.pData =
  5452. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
  5453. + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
  5454. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
  5455. + crp_nbits);
  5456. +
  5457. + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
  5458. + pModExpOpData->exponent.dataLenInBytes);
  5459. + /* Output parameters */
  5460. + pResult->pData =
  5461. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
  5462. + BITS_TO_BYTES(pResult->dataLenInBytes,
  5463. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
  5464. + crp_nbits);
  5465. +
  5466. + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
  5467. + icp_ocfDrvModExpCallBack,
  5468. + callbackTag, pModExpOpData, pResult);
  5469. +
  5470. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5471. + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
  5472. + __FUNCTION__, lacStatus);
  5473. + krp->krp_status = ECANCELED;
  5474. + icp_ocfDrvFreeFlatBuffer(pResult);
  5475. + kmem_cache_free(drvLnModExp_zone, pModExpOpData);
  5476. + }
  5477. +
  5478. + return lacStatus;
  5479. +}
  5480. +
  5481. +/* Name : icp_ocfDrvModExpCRT
  5482. + *
  5483. + * Description : This function will map ordinary Modular Exponentiation Chinese
  5484. + * Remainder Theorem implementaion calls from OCF to the LAC API.
  5485. + *
  5486. + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
  5487. + * decrypt operation. Therefore P and Q input values must always be prime
  5488. + * numbers. Although basic primality checks are done in LAC, it is up to the
  5489. + * user to do any correct prime number checking before passing the inputs.
  5490. + */
  5491. +
  5492. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
  5493. +{
  5494. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5495. + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
  5496. + void *callbackTag = NULL;
  5497. + CpaFlatBuffer *pOutputData = NULL;
  5498. +
  5499. + /*Parameter input checks are all done by LAC, no need to repeat
  5500. + them here. */
  5501. + callbackTag = krp;
  5502. +
  5503. + rsaDecryptOpData = kmem_cache_zalloc(drvRSADecrypt_zone, GFP_KERNEL);
  5504. + if (NULL == rsaDecryptOpData) {
  5505. + APRINTK("%s():Failed to get memory"
  5506. + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
  5507. + krp->krp_status = ENOMEM;
  5508. + return ENOMEM;
  5509. + }
  5510. +
  5511. + rsaDecryptOpData->pRecipientPrivateKey
  5512. + = kmem_cache_zalloc(drvRSAPrivateKey_zone, GFP_KERNEL);
  5513. + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
  5514. + APRINTK("%s():Failed to get memory for MOD EXP CRT"
  5515. + " private key values struct\n", __FUNCTION__);
  5516. + kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
  5517. + krp->krp_status = ENOMEM;
  5518. + return ENOMEM;
  5519. + }
  5520. +
  5521. + rsaDecryptOpData->pRecipientPrivateKey->
  5522. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  5523. + rsaDecryptOpData->pRecipientPrivateKey->
  5524. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  5525. +
  5526. + pOutputData = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5527. + if (NULL == pOutputData) {
  5528. + APRINTK("%s():Failed to get memory"
  5529. + " for MOD EXP CRT output data\n", __FUNCTION__);
  5530. + kmem_cache_free(drvRSAPrivateKey_zone,
  5531. + rsaDecryptOpData->pRecipientPrivateKey);
  5532. + kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
  5533. + krp->krp_status = ENOMEM;
  5534. + return ENOMEM;
  5535. + }
  5536. +
  5537. + rsaDecryptOpData->pRecipientPrivateKey->
  5538. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  5539. + rsaDecryptOpData->pRecipientPrivateKey->
  5540. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  5541. +
  5542. + /* Link parameters */
  5543. + rsaDecryptOpData->inputData.pData =
  5544. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
  5545. + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
  5546. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
  5547. + crp_nbits);
  5548. +
  5549. + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
  5550. + rsaDecryptOpData->inputData.dataLenInBytes);
  5551. +
  5552. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
  5553. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
  5554. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  5555. + prime1P.dataLenInBytes,
  5556. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
  5557. + crp_nbits);
  5558. +
  5559. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5560. + privateKeyRep2.prime1P.pData,
  5561. + rsaDecryptOpData->pRecipientPrivateKey->
  5562. + privateKeyRep2.prime1P.dataLenInBytes);
  5563. +
  5564. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
  5565. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  5566. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  5567. + prime2Q.dataLenInBytes,
  5568. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
  5569. + crp_nbits);
  5570. +
  5571. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5572. + privateKeyRep2.prime2Q.pData,
  5573. + rsaDecryptOpData->pRecipientPrivateKey->
  5574. + privateKeyRep2.prime2Q.dataLenInBytes);
  5575. +
  5576. + rsaDecryptOpData->pRecipientPrivateKey->
  5577. + privateKeyRep2.exponent1Dp.pData =
  5578. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
  5579. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  5580. + exponent1Dp.dataLenInBytes,
  5581. + krp->
  5582. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
  5583. + crp_nbits);
  5584. +
  5585. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5586. + privateKeyRep2.exponent1Dp.pData,
  5587. + rsaDecryptOpData->pRecipientPrivateKey->
  5588. + privateKeyRep2.exponent1Dp.dataLenInBytes);
  5589. +
  5590. + rsaDecryptOpData->pRecipientPrivateKey->
  5591. + privateKeyRep2.exponent2Dq.pData =
  5592. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
  5593. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  5594. + privateKeyRep2.exponent2Dq.dataLenInBytes,
  5595. + krp->
  5596. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
  5597. + crp_nbits);
  5598. +
  5599. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5600. + privateKeyRep2.exponent2Dq.pData,
  5601. + rsaDecryptOpData->pRecipientPrivateKey->
  5602. + privateKeyRep2.exponent2Dq.dataLenInBytes);
  5603. +
  5604. + rsaDecryptOpData->pRecipientPrivateKey->
  5605. + privateKeyRep2.coefficientQInv.pData =
  5606. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
  5607. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  5608. + privateKeyRep2.coefficientQInv.dataLenInBytes,
  5609. + krp->
  5610. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
  5611. + crp_nbits);
  5612. +
  5613. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  5614. + privateKeyRep2.coefficientQInv.pData,
  5615. + rsaDecryptOpData->pRecipientPrivateKey->
  5616. + privateKeyRep2.coefficientQInv.dataLenInBytes);
  5617. +
  5618. + /* Output Parameter */
  5619. + pOutputData->pData =
  5620. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
  5621. + BITS_TO_BYTES(pOutputData->dataLenInBytes,
  5622. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
  5623. + crp_nbits);
  5624. +
  5625. + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
  5626. + icp_ocfDrvModExpCRTCallBack,
  5627. + callbackTag, rsaDecryptOpData, pOutputData);
  5628. +
  5629. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5630. + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
  5631. + __FUNCTION__, lacStatus);
  5632. + krp->krp_status = ECANCELED;
  5633. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  5634. + kmem_cache_free(drvRSAPrivateKey_zone,
  5635. + rsaDecryptOpData->pRecipientPrivateKey);
  5636. + kmem_cache_free(drvRSADecrypt_zone, rsaDecryptOpData);
  5637. + }
  5638. +
  5639. + return lacStatus;
  5640. +}
  5641. +
  5642. +/* Name : icp_ocfDrvCheckALessThanB
  5643. + *
  5644. + * Description : This function will check whether the first argument is less
  5645. + * than the second. It is used to check whether the DSA RS sign Random K
  5646. + * value is less than the Prime Q value (as defined in the specification)
  5647. + *
  5648. + */
  5649. +static int
  5650. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
  5651. +{
  5652. +
  5653. + uint8_t *MSB_K = pK->pData;
  5654. + uint8_t *MSB_Q = pQ->pData;
  5655. + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
  5656. +
  5657. + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
  5658. + return FAIL_A_IS_GREATER_THAN_B;
  5659. + }
  5660. +
  5661. +/*Check MSBs
  5662. +if A == B, check next MSB
  5663. +if A > B, return A_IS_GREATER_THAN_B
  5664. +if A < B, return A_IS_LESS_THAN_B (success)
  5665. +*/
  5666. + while (*MSB_K == *MSB_Q) {
  5667. + MSB_K++;
  5668. + MSB_Q++;
  5669. +
  5670. + buffer_lengths_in_bytes--;
  5671. + if (0 == buffer_lengths_in_bytes) {
  5672. + DPRINTK("%s() Buffers have equal value!!\n",
  5673. + __FUNCTION__);
  5674. + return FAIL_A_IS_EQUAL_TO_B;
  5675. + }
  5676. +
  5677. + }
  5678. +
  5679. + if (*MSB_K < *MSB_Q) {
  5680. + return SUCCESS_A_IS_LESS_THAN_B;
  5681. + } else {
  5682. + return FAIL_A_IS_GREATER_THAN_B;
  5683. + }
  5684. +
  5685. +}
  5686. +
  5687. +/* Name : icp_ocfDrvDsaSign
  5688. + *
  5689. + * Description : This function will map DSA RS Sign from OCF to the LAC API.
  5690. + *
  5691. + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
  5692. + * parameters, OCF expects us to generate the random seed value. This value
  5693. + * is generated and passed to LAC, however the number is discared in the
  5694. + * callback and not returned to the user.
  5695. + */
  5696. +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
  5697. +{
  5698. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5699. + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
  5700. + void *callbackTag = NULL;
  5701. + CpaCyRandGenOpData randGenOpData;
  5702. + int primeQSizeInBytes = 0;
  5703. + int doCheck = 0;
  5704. + CpaFlatBuffer randData;
  5705. + CpaBoolean protocolStatus = CPA_FALSE;
  5706. + CpaFlatBuffer *pR = NULL;
  5707. + CpaFlatBuffer *pS = NULL;
  5708. +
  5709. + callbackTag = krp;
  5710. +
  5711. + BITS_TO_BYTES(primeQSizeInBytes,
  5712. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  5713. + crp_nbits);
  5714. +
  5715. + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
  5716. + APRINTK("%s(): DSA PRIME Q size not equal to the "
  5717. + "FIPS defined 20bytes, = %d\n",
  5718. + __FUNCTION__, primeQSizeInBytes);
  5719. + krp->krp_status = EDOM;
  5720. + return EDOM;
  5721. + }
  5722. +
  5723. + dsaRsSignOpData = kmem_cache_zalloc(drvDSARSSign_zone, GFP_KERNEL);
  5724. + if (NULL == dsaRsSignOpData) {
  5725. + APRINTK("%s():Failed to get memory"
  5726. + " for DSA RS Sign Op data struct\n", __FUNCTION__);
  5727. + krp->krp_status = ENOMEM;
  5728. + return ENOMEM;
  5729. + }
  5730. +
  5731. + dsaRsSignOpData->K.pData =
  5732. + kmem_cache_alloc(drvDSARSSignKValue_zone, GFP_ATOMIC);
  5733. +
  5734. + if (NULL == dsaRsSignOpData->K.pData) {
  5735. + APRINTK("%s():Failed to get memory"
  5736. + " for DSA RS Sign Op Random value\n", __FUNCTION__);
  5737. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5738. + krp->krp_status = ENOMEM;
  5739. + return ENOMEM;
  5740. + }
  5741. +
  5742. + pR = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5743. + if (NULL == pR) {
  5744. + APRINTK("%s():Failed to get memory"
  5745. + " for DSA signature R\n", __FUNCTION__);
  5746. + kmem_cache_free(drvDSARSSignKValue_zone,
  5747. + dsaRsSignOpData->K.pData);
  5748. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5749. + krp->krp_status = ENOMEM;
  5750. + return ENOMEM;
  5751. + }
  5752. +
  5753. + pS = kmem_cache_zalloc(drvFlatBuffer_zone, GFP_KERNEL);
  5754. + if (NULL == pS) {
  5755. + APRINTK("%s():Failed to get memory"
  5756. + " for DSA signature S\n", __FUNCTION__);
  5757. + icp_ocfDrvFreeFlatBuffer(pR);
  5758. + kmem_cache_free(drvDSARSSignKValue_zone,
  5759. + dsaRsSignOpData->K.pData);
  5760. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5761. + krp->krp_status = ENOMEM;
  5762. + return ENOMEM;
  5763. + }
  5764. +
  5765. + /*link prime number parameter for ease of processing */
  5766. + dsaRsSignOpData->P.pData =
  5767. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
  5768. + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
  5769. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
  5770. + crp_nbits);
  5771. +
  5772. + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
  5773. + dsaRsSignOpData->P.dataLenInBytes);
  5774. +
  5775. + dsaRsSignOpData->Q.pData =
  5776. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  5777. + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
  5778. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  5779. + crp_nbits);
  5780. +
  5781. + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
  5782. + dsaRsSignOpData->Q.dataLenInBytes);
  5783. +
  5784. + /*generate random number with equal buffer size to Prime value Q,
  5785. + but value less than Q */
  5786. + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
  5787. +
  5788. + randGenOpData.generateBits = CPA_TRUE;
  5789. + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
  5790. +
  5791. + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
  5792. + dsaRsSignOpData->K.dataLenInBytes,
  5793. + &randData);
  5794. +
  5795. + doCheck = 0;
  5796. + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
  5797. + &(dsaRsSignOpData->Q), &doCheck)) {
  5798. +
  5799. + if (CPA_STATUS_SUCCESS
  5800. + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  5801. + NULL, NULL, &randGenOpData, &randData)) {
  5802. + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
  5803. + "value\n", __FUNCTION__);
  5804. + icp_ocfDrvFreeFlatBuffer(pS);
  5805. + icp_ocfDrvFreeFlatBuffer(pR);
  5806. + kmem_cache_free(drvDSARSSignKValue_zone,
  5807. + dsaRsSignOpData->K.pData);
  5808. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5809. + krp->krp_status = EAGAIN;
  5810. + return EAGAIN;
  5811. + }
  5812. +
  5813. + doCheck++;
  5814. + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
  5815. + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
  5816. + "value less than Q value\n", __FUNCTION__);
  5817. + icp_ocfDrvFreeFlatBuffer(pS);
  5818. + icp_ocfDrvFreeFlatBuffer(pR);
  5819. + kmem_cache_free(drvDSARSSignKValue_zone,
  5820. + dsaRsSignOpData->K.pData);
  5821. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5822. + krp->krp_status = EAGAIN;
  5823. + return EAGAIN;
  5824. + }
  5825. +
  5826. + }
  5827. + /*Rand Data - no need to swap bytes for pK */
  5828. +
  5829. + /* Link parameters */
  5830. + dsaRsSignOpData->G.pData =
  5831. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
  5832. + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
  5833. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
  5834. +
  5835. + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
  5836. + dsaRsSignOpData->G.dataLenInBytes);
  5837. +
  5838. + dsaRsSignOpData->X.pData =
  5839. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
  5840. + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
  5841. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
  5842. + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
  5843. + dsaRsSignOpData->X.dataLenInBytes);
  5844. +
  5845. + dsaRsSignOpData->M.pData =
  5846. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
  5847. + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
  5848. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
  5849. + crp_nbits);
  5850. + icp_ocfDrvSwapBytes(dsaRsSignOpData->M.pData,
  5851. + dsaRsSignOpData->M.dataLenInBytes);
  5852. +
  5853. + /* Output Parameters */
  5854. + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
  5855. + BITS_TO_BYTES(pS->dataLenInBytes,
  5856. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
  5857. + crp_nbits);
  5858. +
  5859. + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
  5860. + BITS_TO_BYTES(pR->dataLenInBytes,
  5861. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
  5862. + crp_nbits);
  5863. +
  5864. + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
  5865. + icp_ocfDrvDsaRSSignCallBack,
  5866. + callbackTag, dsaRsSignOpData,
  5867. + &protocolStatus, pR, pS);
  5868. +
  5869. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5870. + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
  5871. + __FUNCTION__, lacStatus);
  5872. + krp->krp_status = ECANCELED;
  5873. + icp_ocfDrvFreeFlatBuffer(pS);
  5874. + icp_ocfDrvFreeFlatBuffer(pR);
  5875. + kmem_cache_free(drvDSARSSignKValue_zone,
  5876. + dsaRsSignOpData->K.pData);
  5877. + kmem_cache_free(drvDSARSSign_zone, dsaRsSignOpData);
  5878. + }
  5879. +
  5880. + return lacStatus;
  5881. +}
  5882. +
  5883. +/* Name : icp_ocfDrvDsaVerify
  5884. + *
  5885. + * Description : This function will map DSA RS Verify from OCF to the LAC API.
  5886. + *
  5887. + */
  5888. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
  5889. +{
  5890. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5891. + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
  5892. + void *callbackTag = NULL;
  5893. + CpaBoolean verifyStatus = CPA_FALSE;
  5894. +
  5895. + callbackTag = krp;
  5896. +
  5897. + dsaVerifyOpData = kmem_cache_zalloc(drvDSAVerify_zone, GFP_KERNEL);
  5898. + if (NULL == dsaVerifyOpData) {
  5899. + APRINTK("%s():Failed to get memory"
  5900. + " for DSA Verify Op data struct\n", __FUNCTION__);
  5901. + krp->krp_status = ENOMEM;
  5902. + return ENOMEM;
  5903. + }
  5904. +
  5905. + /* Link parameters */
  5906. + dsaVerifyOpData->P.pData =
  5907. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
  5908. + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
  5909. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
  5910. + crp_nbits);
  5911. + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
  5912. + dsaVerifyOpData->P.dataLenInBytes);
  5913. +
  5914. + dsaVerifyOpData->Q.pData =
  5915. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  5916. + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
  5917. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
  5918. + crp_nbits);
  5919. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
  5920. + dsaVerifyOpData->Q.dataLenInBytes);
  5921. +
  5922. + dsaVerifyOpData->G.pData =
  5923. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
  5924. + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
  5925. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
  5926. + crp_nbits);
  5927. + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
  5928. + dsaVerifyOpData->G.dataLenInBytes);
  5929. +
  5930. + dsaVerifyOpData->Y.pData =
  5931. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
  5932. + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
  5933. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
  5934. + crp_nbits);
  5935. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
  5936. + dsaVerifyOpData->Y.dataLenInBytes);
  5937. +
  5938. + dsaVerifyOpData->M.pData =
  5939. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
  5940. + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
  5941. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
  5942. + crp_nbits);
  5943. + icp_ocfDrvSwapBytes(dsaVerifyOpData->M.pData,
  5944. + dsaVerifyOpData->M.dataLenInBytes);
  5945. +
  5946. + dsaVerifyOpData->R.pData =
  5947. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
  5948. + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
  5949. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
  5950. + crp_nbits);
  5951. + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
  5952. + dsaVerifyOpData->R.dataLenInBytes);
  5953. +
  5954. + dsaVerifyOpData->S.pData =
  5955. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
  5956. + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
  5957. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
  5958. + crp_nbits);
  5959. + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
  5960. + dsaVerifyOpData->S.dataLenInBytes);
  5961. +
  5962. + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
  5963. + icp_ocfDrvDsaVerifyCallBack,
  5964. + callbackTag, dsaVerifyOpData, &verifyStatus);
  5965. +
  5966. + if (CPA_STATUS_SUCCESS != lacStatus) {
  5967. + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
  5968. + __FUNCTION__, lacStatus);
  5969. + kmem_cache_free(drvDSAVerify_zone, dsaVerifyOpData);
  5970. + krp->krp_status = ECANCELED;
  5971. + }
  5972. +
  5973. + return lacStatus;
  5974. +}
  5975. +
  5976. +/* Name : icp_ocfDrvReadRandom
  5977. + *
  5978. + * Description : This function will map RNG functionality calls from OCF
  5979. + * to the LAC API.
  5980. + */
  5981. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords)
  5982. +{
  5983. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  5984. + CpaCyRandGenOpData randGenOpData;
  5985. + CpaFlatBuffer randData;
  5986. +
  5987. + if (NULL == buf) {
  5988. + APRINTK("%s(): Invalid input parameters\n", __FUNCTION__);
  5989. + return EINVAL;
  5990. + }
  5991. +
  5992. + /* maxwords here is number of integers to generate data for */
  5993. + randGenOpData.generateBits = CPA_TRUE;
  5994. +
  5995. + randGenOpData.lenInBytes = maxwords * sizeof(uint32_t);
  5996. +
  5997. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *) buf,
  5998. + randGenOpData.lenInBytes, &randData);
  5999. +
  6000. + lacStatus = cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  6001. + NULL, NULL, &randGenOpData, &randData);
  6002. + if (CPA_STATUS_SUCCESS != lacStatus) {
  6003. + EPRINTK("%s(): icp_LacSymRandGen failed (%d). \n",
  6004. + __FUNCTION__, lacStatus);
  6005. + return RETURN_RAND_NUM_GEN_FAILED;
  6006. + }
  6007. +
  6008. + return randGenOpData.lenInBytes / sizeof(uint32_t);
  6009. +}
  6010. +
  6011. +/* Name : icp_ocfDrvDhP1Callback
  6012. + *
  6013. + * Description : When this function returns it signifies that the LAC
  6014. + * component has completed the DH operation.
  6015. + */
  6016. +static void
  6017. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  6018. + CpaStatus status,
  6019. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
  6020. +{
  6021. + struct cryptkop *krp = NULL;
  6022. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  6023. +
  6024. + if (NULL == callbackTag) {
  6025. + DPRINTK("%s(): Invalid input parameters - "
  6026. + "callbackTag data is NULL\n", __FUNCTION__);
  6027. + return;
  6028. + }
  6029. + krp = (struct cryptkop *)callbackTag;
  6030. +
  6031. + if (NULL == pOpData) {
  6032. + DPRINTK("%s(): Invalid input parameters - "
  6033. + "Operation Data is NULL\n", __FUNCTION__);
  6034. + krp->krp_status = ECANCELED;
  6035. + crypto_kdone(krp);
  6036. + return;
  6037. + }
  6038. + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
  6039. +
  6040. + if (NULL == pLocalOctetStringPV) {
  6041. + DPRINTK("%s(): Invalid input parameters - "
  6042. + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
  6043. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  6044. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  6045. + krp->krp_status = ECANCELED;
  6046. + crypto_kdone(krp);
  6047. + return;
  6048. + }
  6049. +
  6050. + if (CPA_STATUS_SUCCESS == status) {
  6051. + krp->krp_status = CRYPTO_OP_SUCCESS;
  6052. + } else {
  6053. + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
  6054. + "Operation Status = %d\n", __FUNCTION__, status);
  6055. + krp->krp_status = ECANCELED;
  6056. + }
  6057. +
  6058. + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
  6059. + pLocalOctetStringPV->dataLenInBytes);
  6060. +
  6061. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  6062. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  6063. + kmem_cache_free(drvDH_zone, pPhase1OpData);
  6064. +
  6065. + crypto_kdone(krp);
  6066. +
  6067. + return;
  6068. +}
  6069. +
  6070. +/* Name : icp_ocfDrvModExpCallBack
  6071. + *
  6072. + * Description : When this function returns it signifies that the LAC
  6073. + * component has completed the Mod Exp operation.
  6074. + */
  6075. +static void
  6076. +icp_ocfDrvModExpCallBack(void *callbackTag,
  6077. + CpaStatus status,
  6078. + void *pOpdata, CpaFlatBuffer * pResult)
  6079. +{
  6080. + struct cryptkop *krp = NULL;
  6081. + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
  6082. +
  6083. + if (NULL == callbackTag) {
  6084. + DPRINTK("%s(): Invalid input parameters - "
  6085. + "callbackTag data is NULL\n", __FUNCTION__);
  6086. + return;
  6087. + }
  6088. + krp = (struct cryptkop *)callbackTag;
  6089. +
  6090. + if (NULL == pOpdata) {
  6091. + DPRINTK("%s(): Invalid Mod Exp input parameters - "
  6092. + "Operation Data is NULL\n", __FUNCTION__);
  6093. + krp->krp_status = ECANCELED;
  6094. + crypto_kdone(krp);
  6095. + return;
  6096. + }
  6097. + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
  6098. +
  6099. + if (NULL == pResult) {
  6100. + DPRINTK("%s(): Invalid input parameters - "
  6101. + "pResult data is NULL\n", __FUNCTION__);
  6102. + krp->krp_status = ECANCELED;
  6103. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  6104. + kmem_cache_free(drvLnModExp_zone, pLnModExpOpData);
  6105. + crypto_kdone(krp);
  6106. + return;
  6107. + }
  6108. +
  6109. + if (CPA_STATUS_SUCCESS == status) {
  6110. + krp->krp_status = CRYPTO_OP_SUCCESS;
  6111. + } else {
  6112. + APRINTK("%s(): LAC Mod Exp Operation failed - "
  6113. + "Operation Status = %d\n", __FUNCTION__, status);
  6114. + krp->krp_status = ECANCELED;
  6115. + }
  6116. +
  6117. + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
  6118. +
  6119. + /*switch base size value back to original */
  6120. + if (pLnModExpOpData->base.pData ==
  6121. + (uint8_t *) & (krp->
  6122. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  6123. + crp_nbits)) {
  6124. + *((uint32_t *) pLnModExpOpData->base.pData) =
  6125. + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
  6126. + }
  6127. + icp_ocfDrvFreeFlatBuffer(pResult);
  6128. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  6129. + kmem_cache_free(drvLnModExp_zone, pLnModExpOpData);
  6130. +
  6131. + crypto_kdone(krp);
  6132. +
  6133. + return;
  6134. +
  6135. +}
  6136. +
  6137. +/* Name : icp_ocfDrvModExpCRTCallBack
  6138. + *
  6139. + * Description : When this function returns it signifies that the LAC
  6140. + * component has completed the Mod Exp CRT operation.
  6141. + */
  6142. +static void
  6143. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  6144. + CpaStatus status,
  6145. + void *pOpData, CpaFlatBuffer * pOutputData)
  6146. +{
  6147. + struct cryptkop *krp = NULL;
  6148. + CpaCyRsaDecryptOpData *pDecryptData = NULL;
  6149. +
  6150. + if (NULL == callbackTag) {
  6151. + DPRINTK("%s(): Invalid input parameters - "
  6152. + "callbackTag data is NULL\n", __FUNCTION__);
  6153. + return;
  6154. + }
  6155. +
  6156. + krp = (struct cryptkop *)callbackTag;
  6157. +
  6158. + if (NULL == pOpData) {
  6159. + DPRINTK("%s(): Invalid input parameters - "
  6160. + "Operation Data is NULL\n", __FUNCTION__);
  6161. + krp->krp_status = ECANCELED;
  6162. + crypto_kdone(krp);
  6163. + return;
  6164. + }
  6165. + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
  6166. +
  6167. + if (NULL == pOutputData) {
  6168. + DPRINTK("%s(): Invalid input parameter - "
  6169. + "pOutputData is NULL\n", __FUNCTION__);
  6170. + memset(pDecryptData->pRecipientPrivateKey, 0,
  6171. + sizeof(CpaCyRsaPrivateKey));
  6172. + kmem_cache_free(drvRSAPrivateKey_zone,
  6173. + pDecryptData->pRecipientPrivateKey);
  6174. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  6175. + kmem_cache_free(drvRSADecrypt_zone, pDecryptData);
  6176. + krp->krp_status = ECANCELED;
  6177. + crypto_kdone(krp);
  6178. + return;
  6179. + }
  6180. +
  6181. + if (CPA_STATUS_SUCCESS == status) {
  6182. + krp->krp_status = CRYPTO_OP_SUCCESS;
  6183. + } else {
  6184. + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
  6185. + "Operation Status = %d\n", __FUNCTION__, status);
  6186. + krp->krp_status = ECANCELED;
  6187. + }
  6188. +
  6189. + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
  6190. +
  6191. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  6192. + memset(pDecryptData->pRecipientPrivateKey, 0,
  6193. + sizeof(CpaCyRsaPrivateKey));
  6194. + kmem_cache_free(drvRSAPrivateKey_zone,
  6195. + pDecryptData->pRecipientPrivateKey);
  6196. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  6197. + kmem_cache_free(drvRSADecrypt_zone, pDecryptData);
  6198. +
  6199. + crypto_kdone(krp);
  6200. +
  6201. + return;
  6202. +}
  6203. +
  6204. +/* Name : icp_ocfDrvDsaRSSignCallBack
  6205. + *
  6206. + * Description : When this function returns it signifies that the LAC
  6207. + * component has completed the DSA RS sign operation.
  6208. + */
  6209. +static void
  6210. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  6211. + CpaStatus status,
  6212. + void *pOpData,
  6213. + CpaBoolean protocolStatus,
  6214. + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
  6215. +{
  6216. + struct cryptkop *krp = NULL;
  6217. + CpaCyDsaRSSignOpData *pSignData = NULL;
  6218. +
  6219. + if (NULL == callbackTag) {
  6220. + DPRINTK("%s(): Invalid input parameters - "
  6221. + "callbackTag data is NULL\n", __FUNCTION__);
  6222. + return;
  6223. + }
  6224. +
  6225. + krp = (struct cryptkop *)callbackTag;
  6226. +
  6227. + if (NULL == pOpData) {
  6228. + DPRINTK("%s(): Invalid input parameters - "
  6229. + "Operation Data is NULL\n", __FUNCTION__);
  6230. + krp->krp_status = ECANCELED;
  6231. + crypto_kdone(krp);
  6232. + return;
  6233. + }
  6234. + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
  6235. +
  6236. + if (NULL == pR) {
  6237. + DPRINTK("%s(): Invalid input parameter - "
  6238. + "pR sign is NULL\n", __FUNCTION__);
  6239. + icp_ocfDrvFreeFlatBuffer(pS);
  6240. + kmem_cache_free(drvDSARSSign_zone, pSignData);
  6241. + krp->krp_status = ECANCELED;
  6242. + crypto_kdone(krp);
  6243. + return;
  6244. + }
  6245. +
  6246. + if (NULL == pS) {
  6247. + DPRINTK("%s(): Invalid input parameter - "
  6248. + "pS sign is NULL\n", __FUNCTION__);
  6249. + icp_ocfDrvFreeFlatBuffer(pR);
  6250. + kmem_cache_free(drvDSARSSign_zone, pSignData);
  6251. + krp->krp_status = ECANCELED;
  6252. + crypto_kdone(krp);
  6253. + return;
  6254. + }
  6255. +
  6256. + if (CPA_STATUS_SUCCESS != status) {
  6257. + APRINTK("%s(): LAC DSA RS Sign operation failed - "
  6258. + "Operation Status = %d\n", __FUNCTION__, status);
  6259. + krp->krp_status = ECANCELED;
  6260. + } else {
  6261. + krp->krp_status = CRYPTO_OP_SUCCESS;
  6262. +
  6263. + if (CPA_TRUE != protocolStatus) {
  6264. + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
  6265. + "to protocol error\n", __FUNCTION__);
  6266. + krp->krp_status = EIO;
  6267. + }
  6268. + }
  6269. +
  6270. + /* Swap bytes only when the callback status is successful and
  6271. + protocolStatus is set to true */
  6272. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
  6273. + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
  6274. + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
  6275. + }
  6276. +
  6277. + icp_ocfDrvFreeFlatBuffer(pR);
  6278. + icp_ocfDrvFreeFlatBuffer(pS);
  6279. + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
  6280. + kmem_cache_free(drvDSARSSignKValue_zone, pSignData->K.pData);
  6281. + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
  6282. + kmem_cache_free(drvDSARSSign_zone, pSignData);
  6283. + crypto_kdone(krp);
  6284. +
  6285. + return;
  6286. +}
  6287. +
  6288. +/* Name : icp_ocfDrvDsaVerifyCallback
  6289. + *
  6290. + * Description : When this function returns it signifies that the LAC
  6291. + * component has completed the DSA Verify operation.
  6292. + */
  6293. +static void
  6294. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  6295. + CpaStatus status,
  6296. + void *pOpData, CpaBoolean verifyStatus)
  6297. +{
  6298. +
  6299. + struct cryptkop *krp = NULL;
  6300. + CpaCyDsaVerifyOpData *pVerData = NULL;
  6301. +
  6302. + if (NULL == callbackTag) {
  6303. + DPRINTK("%s(): Invalid input parameters - "
  6304. + "callbackTag data is NULL\n", __FUNCTION__);
  6305. + return;
  6306. + }
  6307. +
  6308. + krp = (struct cryptkop *)callbackTag;
  6309. +
  6310. + if (NULL == pOpData) {
  6311. + DPRINTK("%s(): Invalid input parameters - "
  6312. + "Operation Data is NULL\n", __FUNCTION__);
  6313. + krp->krp_status = ECANCELED;
  6314. + crypto_kdone(krp);
  6315. + return;
  6316. + }
  6317. + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
  6318. +
  6319. + if (CPA_STATUS_SUCCESS != status) {
  6320. + APRINTK("%s(): LAC DSA Verify operation failed - "
  6321. + "Operation Status = %d\n", __FUNCTION__, status);
  6322. + krp->krp_status = ECANCELED;
  6323. + } else {
  6324. + krp->krp_status = CRYPTO_OP_SUCCESS;
  6325. +
  6326. + if (CPA_TRUE != verifyStatus) {
  6327. + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
  6328. + krp->krp_status = EIO;
  6329. + }
  6330. + }
  6331. +
  6332. + /* Swap bytes only when the callback status is successful and
  6333. + verifyStatus is set to true */
  6334. + /*Just swapping back the key values for now. Possibly all
  6335. + swapped buffers need to be reverted */
  6336. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
  6337. + icp_ocfDrvSwapBytes(pVerData->R.pData,
  6338. + pVerData->R.dataLenInBytes);
  6339. + icp_ocfDrvSwapBytes(pVerData->S.pData,
  6340. + pVerData->S.dataLenInBytes);
  6341. + }
  6342. +
  6343. + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
  6344. + kmem_cache_free(drvDSAVerify_zone, pVerData);
  6345. + crypto_kdone(krp);
  6346. +
  6347. + return;
  6348. +}
  6349. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.29.1/crypto/ocf/ep80579/icp_common.c
  6350. --- linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
  6351. +++ linux-2.6.29.1/crypto/ocf/ep80579/icp_common.c 2009-04-20 20:01:21.432551806 +0200
  6352. @@ -0,0 +1,891 @@
  6353. +/***************************************************************************
  6354. + *
  6355. + * This file is provided under a dual BSD/GPLv2 license. When using or
  6356. + * redistributing this file, you may do so under either license.
  6357. + *
  6358. + * GPL LICENSE SUMMARY
  6359. + *
  6360. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  6361. + *
  6362. + * This program is free software; you can redistribute it and/or modify
  6363. + * it under the terms of version 2 of the GNU General Public License as
  6364. + * published by the Free Software Foundation.
  6365. + *
  6366. + * This program is distributed in the hope that it will be useful, but
  6367. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  6368. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  6369. + * General Public License for more details.
  6370. + *
  6371. + * You should have received a copy of the GNU General Public License
  6372. + * along with this program; if not, write to the Free Software
  6373. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  6374. + * The full GNU General Public License is included in this distribution
  6375. + * in the file called LICENSE.GPL.
  6376. + *
  6377. + * Contact Information:
  6378. + * Intel Corporation
  6379. + *
  6380. + * BSD LICENSE
  6381. + *
  6382. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  6383. + * All rights reserved.
  6384. + *
  6385. + * Redistribution and use in source and binary forms, with or without
  6386. + * modification, are permitted provided that the following conditions
  6387. + * are met:
  6388. + *
  6389. + * * Redistributions of source code must retain the above copyright
  6390. + * notice, this list of conditions and the following disclaimer.
  6391. + * * Redistributions in binary form must reproduce the above copyright
  6392. + * notice, this list of conditions and the following disclaimer in
  6393. + * the documentation and/or other materials provided with the
  6394. + * distribution.
  6395. + * * Neither the name of Intel Corporation nor the names of its
  6396. + * contributors may be used to endorse or promote products derived
  6397. + * from this software without specific prior written permission.
  6398. + *
  6399. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6400. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  6401. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6402. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  6403. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  6404. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  6405. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  6406. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  6407. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  6408. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  6409. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  6410. + *
  6411. + *
  6412. + * version: Security.L.1.0.130
  6413. + *
  6414. + ***************************************************************************/
  6415. +
  6416. +/*
  6417. + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  6418. + * crypto.
  6419. + *
  6420. + * This driver requires the ICP Access Library that is available from Intel in
  6421. + * order to operate.
  6422. + */
  6423. +
  6424. +#include "icp_ocf.h"
  6425. +
  6426. +#define ICP_OCF_COMP_NAME "ICP_OCF"
  6427. +#define ICP_OCF_VER_MAIN (2)
  6428. +#define ICP_OCF_VER_MJR (0)
  6429. +#define ICP_OCF_VER_MNR (0)
  6430. +
  6431. +#define MAX_DEREG_RETRIES (100)
  6432. +#define DEFAULT_DEREG_RETRIES (10)
  6433. +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  6434. +
  6435. +/* This defines the maximum number of sessions possible between OCF
  6436. + and the OCF Tolapai Driver. If set to zero, there is no limit. */
  6437. +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  6438. +#define NUM_SUPPORTED_CAPABILITIES (21)
  6439. +
  6440. +/*Slabs zones*/
  6441. +struct kmem_cache *drvSessionData_zone = NULL;
  6442. +struct kmem_cache *drvOpData_zone = NULL;
  6443. +struct kmem_cache *drvDH_zone = NULL;
  6444. +struct kmem_cache *drvLnModExp_zone = NULL;
  6445. +struct kmem_cache *drvRSADecrypt_zone = NULL;
  6446. +struct kmem_cache *drvRSAPrivateKey_zone = NULL;
  6447. +struct kmem_cache *drvDSARSSign_zone = NULL;
  6448. +struct kmem_cache *drvDSARSSignKValue_zone = NULL;
  6449. +struct kmem_cache *drvDSAVerify_zone = NULL;
  6450. +
  6451. +/*Slab zones for flatbuffers and bufferlist*/
  6452. +struct kmem_cache *drvFlatBuffer_zone = NULL;
  6453. +
  6454. +static int icp_ocfDrvInit(void);
  6455. +static void icp_ocfDrvExit(void);
  6456. +static void icp_ocfDrvFreeCaches(void);
  6457. +static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
  6458. +
  6459. +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  6460. +
  6461. +/* Module parameter - gives the number of times LAC deregistration shall be
  6462. + re-tried */
  6463. +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  6464. +
  6465. +/* Module parameter - gives the delay time in jiffies before a LAC session
  6466. + shall be attempted to be deregistered again */
  6467. +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  6468. +
  6469. +/* Module parameter - gives the maximum number of sessions possible between
  6470. + OCF and the OCF Tolapai Driver. If set to zero, there is no limit.*/
  6471. +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  6472. +
  6473. +/* This is set when the module is removed from the system, no further
  6474. + processing can take place if this is set */
  6475. +atomic_t icp_ocfDrvIsExiting = ATOMIC_INIT(0);
  6476. +
  6477. +/* This is used to show how many lac sessions were not deregistered*/
  6478. +atomic_t lac_session_failed_dereg_count = ATOMIC_INIT(0);
  6479. +
  6480. +/* This is used to track the number of registered sessions between OCF and
  6481. + * and the OCF Tolapai driver, when max_session is set to value other than
  6482. + * zero. This ensures that the max_session set for the OCF and the driver
  6483. + * is equal to the LAC registered sessions */
  6484. +atomic_t num_ocf_to_drv_registered_sessions = ATOMIC_INIT(0);
  6485. +
  6486. +/* Head of linked list used to store session data */
  6487. +struct list_head icp_ocfDrvGlobalSymListHead;
  6488. +struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
  6489. +
  6490. +spinlock_t icp_ocfDrvSymSessInfoListSpinlock = SPIN_LOCK_UNLOCKED;
  6491. +rwlock_t icp_kmem_cache_destroy_alloc_lock = RW_LOCK_UNLOCKED;
  6492. +
  6493. +struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
  6494. +
  6495. +struct icp_drvBuffListInfo defBuffListInfo;
  6496. +
  6497. +static struct {
  6498. + softc_device_decl sc_dev;
  6499. +} icpDev;
  6500. +
  6501. +static device_method_t icp_methods = {
  6502. + /* crypto device methods */
  6503. + DEVMETHOD(cryptodev_newsession, icp_ocfDrvNewSession),
  6504. + DEVMETHOD(cryptodev_freesession, icp_ocfDrvFreeLACSession),
  6505. + DEVMETHOD(cryptodev_process, icp_ocfDrvSymProcess),
  6506. + DEVMETHOD(cryptodev_kprocess, icp_ocfDrvPkeProcess),
  6507. +};
  6508. +
  6509. +module_param(num_dereg_retries, int, S_IRUGO);
  6510. +module_param(dereg_retry_delay_in_jiffies, int, S_IRUGO);
  6511. +module_param(max_sessions, int, S_IRUGO);
  6512. +
  6513. +MODULE_PARM_DESC(num_dereg_retries,
  6514. + "Number of times to retry LAC Sym Session Deregistration. "
  6515. + "Default 10, Max 100");
  6516. +MODULE_PARM_DESC(dereg_retry_delay_in_jiffies, "Delay in jiffies "
  6517. + "(added to a schedule() function call) before a LAC Sym "
  6518. + "Session Dereg is retried. Default 10");
  6519. +MODULE_PARM_DESC(max_sessions, "This sets the maximum number of sessions "
  6520. + "between OCF and this driver. If this value is set to zero, "
  6521. + "max session count checking is disabled. Default is zero(0)");
  6522. +
  6523. +/* Name : icp_ocfDrvInit
  6524. + *
  6525. + * Description : This function will register all the symmetric and asymmetric
  6526. + * functionality that will be accelerated by the hardware. It will also
  6527. + * get a unique driver ID from the OCF and initialise all slab caches
  6528. + */
  6529. +static int __init icp_ocfDrvInit(void)
  6530. +{
  6531. + int ocfStatus = 0;
  6532. +
  6533. + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  6534. + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  6535. +
  6536. + if (MAX_DEREG_RETRIES < num_dereg_retries) {
  6537. + EPRINTK("Session deregistration retry count set to greater "
  6538. + "than %d", MAX_DEREG_RETRIES);
  6539. + return -1;
  6540. + }
  6541. +
  6542. + /* Initialize and Start the Cryptographic component */
  6543. + if (CPA_STATUS_SUCCESS !=
  6544. + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  6545. + EPRINTK("Failed to initialize and start the instance "
  6546. + "of the Cryptographic component.\n");
  6547. + return -1;
  6548. + }
  6549. +
  6550. + /* Set the default size of BufferList to allocate */
  6551. + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  6552. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  6553. + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  6554. + &defBuffListInfo)) {
  6555. + EPRINTK("Failed to get bufferlist memory info.\n");
  6556. + return -1;
  6557. + }
  6558. +
  6559. + /*Register OCF Tolapai Driver with OCF */
  6560. + memset(&icpDev, 0, sizeof(icpDev));
  6561. + softc_device_init(&icpDev, "icp", 0, icp_methods);
  6562. +
  6563. + icp_ocfDrvDriverId = crypto_get_driverid(softc_get_device(&icpDev),
  6564. + CRYPTOCAP_F_HARDWARE);
  6565. +
  6566. + if (icp_ocfDrvDriverId < 0) {
  6567. + EPRINTK("%s : ICP driver failed to register with OCF!\n",
  6568. + __FUNCTION__);
  6569. + return -ENODEV;
  6570. + }
  6571. +
  6572. + /*Create all the slab caches used by the OCF Tolapai Driver */
  6573. + drvSessionData_zone =
  6574. + ICP_CACHE_CREATE("ICP Session Data", struct icp_drvSessionData);
  6575. + ICP_CACHE_NULL_CHECK(drvSessionData_zone);
  6576. +
  6577. + /*
  6578. + * Allocation of the OpData includes the allocation space for meta data.
  6579. + * The memory after the opData structure is reserved for this meta data.
  6580. + */
  6581. + drvOpData_zone =
  6582. + kmem_cache_create("ICP Op Data", sizeof(struct icp_drvOpData) +
  6583. + defBuffListInfo.metaSize ,0, SLAB_HWCACHE_ALIGN, NULL, NULL);
  6584. +
  6585. +
  6586. + ICP_CACHE_NULL_CHECK(drvOpData_zone);
  6587. +
  6588. + drvDH_zone = ICP_CACHE_CREATE("ICP DH data", CpaCyDhPhase1KeyGenOpData);
  6589. + ICP_CACHE_NULL_CHECK(drvDH_zone);
  6590. +
  6591. + drvLnModExp_zone =
  6592. + ICP_CACHE_CREATE("ICP ModExp data", CpaCyLnModExpOpData);
  6593. + ICP_CACHE_NULL_CHECK(drvLnModExp_zone);
  6594. +
  6595. + drvRSADecrypt_zone =
  6596. + ICP_CACHE_CREATE("ICP RSA decrypt data", CpaCyRsaDecryptOpData);
  6597. + ICP_CACHE_NULL_CHECK(drvRSADecrypt_zone);
  6598. +
  6599. + drvRSAPrivateKey_zone =
  6600. + ICP_CACHE_CREATE("ICP RSA private key data", CpaCyRsaPrivateKey);
  6601. + ICP_CACHE_NULL_CHECK(drvRSAPrivateKey_zone);
  6602. +
  6603. + drvDSARSSign_zone =
  6604. + ICP_CACHE_CREATE("ICP DSA Sign", CpaCyDsaRSSignOpData);
  6605. + ICP_CACHE_NULL_CHECK(drvDSARSSign_zone);
  6606. +
  6607. + /*too awkward to use a macro here */
  6608. + drvDSARSSignKValue_zone =
  6609. + kmem_cache_create("ICP DSA Sign Rand Val",
  6610. + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES, 0,
  6611. + SLAB_HWCACHE_ALIGN, NULL, NULL);
  6612. + ICP_CACHE_NULL_CHECK(drvDSARSSignKValue_zone);
  6613. +
  6614. + drvDSAVerify_zone =
  6615. + ICP_CACHE_CREATE("ICP DSA Verify", CpaCyDsaVerifyOpData);
  6616. + ICP_CACHE_NULL_CHECK(drvDSAVerify_zone);
  6617. +
  6618. + drvFlatBuffer_zone =
  6619. + ICP_CACHE_CREATE("ICP Flat Buffers", CpaFlatBuffer);
  6620. + ICP_CACHE_NULL_CHECK(drvFlatBuffer_zone);
  6621. +
  6622. + /* Register the ICP symmetric crypto support. */
  6623. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_NULL_CBC);
  6624. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_DES_CBC);
  6625. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_3DES_CBC);
  6626. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_AES_CBC);
  6627. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_ARC4);
  6628. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5);
  6629. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5_HMAC);
  6630. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1);
  6631. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1_HMAC);
  6632. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256);
  6633. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256_HMAC);
  6634. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384);
  6635. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384_HMAC);
  6636. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512);
  6637. + ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512_HMAC);
  6638. +
  6639. + /* Register the ICP asymmetric algorithm support */
  6640. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DH_COMPUTE_KEY);
  6641. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP);
  6642. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP_CRT);
  6643. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_SIGN);
  6644. + ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_VERIFY);
  6645. +
  6646. + /* Register the ICP random number generator support */
  6647. + if (OCF_REGISTRATION_STATUS_SUCCESS ==
  6648. + crypto_rregister(icp_ocfDrvDriverId, icp_ocfDrvReadRandom, NULL)) {
  6649. + ocfStatus++;
  6650. + }
  6651. +
  6652. + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  6653. + DPRINTK("%s: Failed to register any device capabilities\n",
  6654. + __FUNCTION__);
  6655. + icp_ocfDrvFreeCaches();
  6656. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  6657. + return -ECANCELED;
  6658. + }
  6659. +
  6660. + DPRINTK("%s: Registered %d of %d device capabilities\n",
  6661. + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  6662. +
  6663. +/*Session data linked list used during module exit*/
  6664. + INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  6665. + INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  6666. +
  6667. + icp_ocfDrvFreeLacSessionWorkQ =
  6668. + create_singlethread_workqueue("ocfLacDeregWorkQueue");
  6669. +
  6670. + return 0;
  6671. +}
  6672. +
  6673. +/* Name : icp_ocfDrvExit
  6674. + *
  6675. + * Description : This function will deregister all the symmetric sessions
  6676. + * registered with the LAC component. It will also deregister all symmetric
  6677. + * and asymmetric functionality that can be accelerated by the hardware via OCF
  6678. + * and random number generation if it is enabled.
  6679. + */
  6680. +static void icp_ocfDrvExit(void)
  6681. +{
  6682. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  6683. + struct icp_drvSessionData *sessionData = NULL;
  6684. + struct icp_drvSessionData *tempSessionData = NULL;
  6685. + int i, remaining_delay_time_in_jiffies = 0;
  6686. + /* There is a possibility of a process or new session command being */
  6687. + /* sent before this variable is incremented. The aim of this variable */
  6688. + /* is to stop a loop of calls creating a deadlock situation which */
  6689. + /* would prevent the driver from exiting. */
  6690. +
  6691. + atomic_inc(&icp_ocfDrvIsExiting);
  6692. +
  6693. + /*Existing sessions will be routed to another driver after these calls */
  6694. + crypto_unregister_all(icp_ocfDrvDriverId);
  6695. + crypto_runregister_all(icp_ocfDrvDriverId);
  6696. +
  6697. + /*If any sessions are waiting to be deregistered, do that. This also
  6698. + flushes the work queue */
  6699. + destroy_workqueue(icp_ocfDrvFreeLacSessionWorkQ);
  6700. +
  6701. + /*ENTER CRITICAL SECTION */
  6702. + spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  6703. + list_for_each_entry_safe(tempSessionData, sessionData,
  6704. + &icp_ocfDrvGlobalSymListHead, listNode) {
  6705. + for (i = 0; i < num_dereg_retries; i++) {
  6706. + /*No harm if bad input - LAC will handle error cases */
  6707. + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  6708. + lacStatus =
  6709. + cpaCySymRemoveSession
  6710. + (CPA_INSTANCE_HANDLE_SINGLE,
  6711. + tempSessionData->sessHandle);
  6712. + if (CPA_STATUS_SUCCESS == lacStatus) {
  6713. + /* Succesfully deregistered */
  6714. + break;
  6715. + } else if (CPA_STATUS_RETRY != lacStatus) {
  6716. + atomic_inc
  6717. + (&lac_session_failed_dereg_count);
  6718. + break;
  6719. + }
  6720. +
  6721. + /*schedule_timout returns the time left for completion if
  6722. + * this task is set to TASK_INTERRUPTIBLE */
  6723. + remaining_delay_time_in_jiffies =
  6724. + dereg_retry_delay_in_jiffies;
  6725. + while (0 > remaining_delay_time_in_jiffies) {
  6726. + remaining_delay_time_in_jiffies =
  6727. + schedule_timeout
  6728. + (remaining_delay_time_in_jiffies);
  6729. + }
  6730. +
  6731. + DPRINTK
  6732. + ("%s(): Retry %d to deregistrate the session\n",
  6733. + __FUNCTION__, i);
  6734. + }
  6735. + }
  6736. +
  6737. + /*remove from current list */
  6738. + list_del(&(tempSessionData->listNode));
  6739. + /*add to free mem linked list */
  6740. + list_add(&(tempSessionData->listNode),
  6741. + &icp_ocfDrvGlobalSymListHead_FreeMemList);
  6742. +
  6743. + }
  6744. +
  6745. + /*EXIT CRITICAL SECTION */
  6746. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  6747. +
  6748. + /*set back to initial values */
  6749. + sessionData = NULL;
  6750. + /*still have a reference in our list! */
  6751. + tempSessionData = NULL;
  6752. + /*free memory */
  6753. + list_for_each_entry_safe(tempSessionData, sessionData,
  6754. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  6755. + listNode) {
  6756. +
  6757. + list_del(&(tempSessionData->listNode));
  6758. + /* Free allocated CpaCySymSessionCtx */
  6759. + if (NULL != tempSessionData->sessHandle) {
  6760. + kfree(tempSessionData->sessHandle);
  6761. + }
  6762. + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  6763. + kmem_cache_free(drvSessionData_zone, tempSessionData);
  6764. + }
  6765. +
  6766. + if (0 != atomic_read(&lac_session_failed_dereg_count)) {
  6767. + DPRINTK("%s(): %d LAC sessions were not deregistered "
  6768. + "correctly. This is not a clean exit! \n",
  6769. + __FUNCTION__,
  6770. + atomic_read(&lac_session_failed_dereg_count));
  6771. + }
  6772. +
  6773. + icp_ocfDrvFreeCaches();
  6774. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  6775. +
  6776. + /* Shutdown the Cryptographic component */
  6777. + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  6778. + if (CPA_STATUS_SUCCESS != lacStatus) {
  6779. + DPRINTK("%s(): Failed to stop instance of the "
  6780. + "Cryptographic component.(status == %d)\n",
  6781. + __FUNCTION__, lacStatus);
  6782. + }
  6783. +
  6784. +}
  6785. +
  6786. +/* Name : icp_ocfDrvFreeCaches
  6787. + *
  6788. + * Description : This function deregisters all slab caches
  6789. + */
  6790. +static void icp_ocfDrvFreeCaches(void)
  6791. +{
  6792. + if (atomic_read(&icp_ocfDrvIsExiting) != CPA_TRUE) {
  6793. + atomic_set(&icp_ocfDrvIsExiting, 1);
  6794. + }
  6795. +
  6796. + /*Sym Zones */
  6797. + ICP_CACHE_DESTROY(drvSessionData_zone);
  6798. + ICP_CACHE_DESTROY(drvOpData_zone);
  6799. +
  6800. + /*Asym zones */
  6801. + ICP_CACHE_DESTROY(drvDH_zone);
  6802. + ICP_CACHE_DESTROY(drvLnModExp_zone);
  6803. + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  6804. + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  6805. + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  6806. + ICP_CACHE_DESTROY(drvDSARSSign_zone);
  6807. + ICP_CACHE_DESTROY(drvDSAVerify_zone);
  6808. +
  6809. + /*FlatBuffer and BufferList Zones */
  6810. + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  6811. +
  6812. +}
  6813. +
  6814. +/* Name : icp_ocfDrvDeregRetry
  6815. + *
  6816. + * Description : This function will try to farm the session deregistration
  6817. + * off to a work queue. If it fails, nothing more can be done and it
  6818. + * returns an error
  6819. + */
  6820. +
  6821. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  6822. +{
  6823. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  6824. +
  6825. + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  6826. + __FUNCTION__, sessionToDeregister);
  6827. +
  6828. + /*make sure the session is not available to be allocated during this
  6829. + process */
  6830. + atomic_inc(&lac_session_failed_dereg_count);
  6831. +
  6832. + /*Farm off to work queue */
  6833. + workstore =
  6834. + kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), GFP_ATOMIC);
  6835. + if (NULL == workstore) {
  6836. + DPRINTK("%s(): unable to free session - no memory available "
  6837. + "for work queue\n", __FUNCTION__);
  6838. + return ENOMEM;
  6839. + }
  6840. +
  6841. + workstore->sessionToDeregister = sessionToDeregister;
  6842. +
  6843. + INIT_WORK(&(workstore->work), icp_ocfDrvDeferedFreeLacSessionProcess,
  6844. + workstore);
  6845. + queue_work(icp_ocfDrvFreeLacSessionWorkQ, &(workstore->work));
  6846. +
  6847. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6848. +
  6849. +}
  6850. +
  6851. +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  6852. + *
  6853. + * Description : This function will retry (module input parameter)
  6854. + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  6855. + * CPA_STATUS_RETRY message from the LAC component. This function is run in
  6856. + * Thread context because it is called from a worker thread
  6857. + */
  6858. +static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  6859. +{
  6860. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  6861. + CpaCySymSessionCtx sessionToDeregister = NULL;
  6862. + int i = 0;
  6863. + int remaining_delay_time_in_jiffies = 0;
  6864. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  6865. +
  6866. + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  6867. + if (NULL == workstore) {
  6868. + DPRINTK("%s() function called with null parameter \n",
  6869. + __FUNCTION__);
  6870. + return;
  6871. + }
  6872. +
  6873. + sessionToDeregister = workstore->sessionToDeregister;
  6874. + kfree(workstore);
  6875. +
  6876. + /*if exiting, give deregistration one more blast only */
  6877. + if (atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  6878. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  6879. + sessionToDeregister);
  6880. +
  6881. + if (lacStatus != CPA_STATUS_SUCCESS) {
  6882. + DPRINTK("%s() Failed to Dereg LAC session %p "
  6883. + "during module exit\n", __FUNCTION__,
  6884. + sessionToDeregister);
  6885. + return;
  6886. + }
  6887. +
  6888. + atomic_dec(&lac_session_failed_dereg_count);
  6889. + return;
  6890. + }
  6891. +
  6892. + for (i = 0; i <= num_dereg_retries; i++) {
  6893. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  6894. + sessionToDeregister);
  6895. +
  6896. + if (lacStatus == CPA_STATUS_SUCCESS) {
  6897. + atomic_dec(&lac_session_failed_dereg_count);
  6898. + return;
  6899. + }
  6900. + if (lacStatus != CPA_STATUS_RETRY) {
  6901. + DPRINTK("%s() Failed to deregister session - lacStatus "
  6902. + " = %d", __FUNCTION__, lacStatus);
  6903. + break;
  6904. + }
  6905. +
  6906. + /*schedule_timout returns the time left for completion if this
  6907. + task is set to TASK_INTERRUPTIBLE */
  6908. + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  6909. + while (0 > remaining_delay_time_in_jiffies) {
  6910. + remaining_delay_time_in_jiffies =
  6911. + schedule_timeout(remaining_delay_time_in_jiffies);
  6912. + }
  6913. +
  6914. + }
  6915. +
  6916. + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  6917. + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  6918. + atomic_read(&lac_session_failed_dereg_count));
  6919. +}
  6920. +
  6921. +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  6922. + *
  6923. + * Description : This function converts a "pointer and length" buffer
  6924. + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  6925. + *
  6926. + * This function assumes that the data passed in are valid.
  6927. + */
  6928. +inline void
  6929. +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  6930. + CpaFlatBuffer * pFlatBuffer)
  6931. +{
  6932. + pFlatBuffer->pData = pData;
  6933. + pFlatBuffer->dataLenInBytes = len;
  6934. +}
  6935. +
  6936. +/* Name : icp_ocfDrvSingleSkBuffToFlatBuffer
  6937. + *
  6938. + * Description : This function converts a single socket buffer (sk_buff)
  6939. + * structure to a Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  6940. + *
  6941. + * This function assumes that the data passed in are valid.
  6942. + */
  6943. +static inline void
  6944. +icp_ocfDrvSingleSkBuffToFlatBuffer(struct sk_buff *pSkb,
  6945. + CpaFlatBuffer * pFlatBuffer)
  6946. +{
  6947. + pFlatBuffer->pData = pSkb->data;
  6948. + pFlatBuffer->dataLenInBytes = skb_headlen(pSkb);
  6949. +}
  6950. +
  6951. +/* Name : icp_ocfDrvSkBuffToBufferList
  6952. + *
  6953. + * Description : This function converts a socket buffer (sk_buff) structure to
  6954. + * Fredericksburg Scatter/Gather (CpaBufferList) buffer format.
  6955. + *
  6956. + * This function assumes that the bufferlist has been allocated with the correct
  6957. + * number of buffer arrays.
  6958. + *
  6959. + */
  6960. +inline int
  6961. +icp_ocfDrvSkBuffToBufferList(struct sk_buff *pSkb, CpaBufferList * bufferList)
  6962. +{
  6963. + CpaFlatBuffer *curFlatBuffer = NULL;
  6964. + char *skbuffPageAddr = NULL;
  6965. + struct sk_buff *pCurFrag = NULL;
  6966. + struct skb_shared_info *pShInfo = NULL;
  6967. + uint32_t page_offset = 0, i = 0;
  6968. +
  6969. + DPRINTK("%s(): Entry Point\n", __FUNCTION__);
  6970. +
  6971. + /*
  6972. + * In all cases, the first skb needs to be translated to FlatBuffer.
  6973. + * Perform a buffer translation for the first skbuff
  6974. + */
  6975. + curFlatBuffer = bufferList->pBuffers;
  6976. + icp_ocfDrvSingleSkBuffToFlatBuffer(pSkb, curFlatBuffer);
  6977. +
  6978. + /* Set the userData to point to the original sk_buff */
  6979. + bufferList->pUserData = (void *)pSkb;
  6980. +
  6981. + /* We now know we'll have at least one element in the SGL */
  6982. + bufferList->numBuffers = 1;
  6983. +
  6984. + if (0 == skb_is_nonlinear(pSkb)) {
  6985. + /* Is a linear buffer - therefore it's a single skbuff */
  6986. + DPRINTK("%s(): Exit Point\n", __FUNCTION__);
  6987. + return ICP_OCF_DRV_STATUS_SUCCESS;
  6988. + }
  6989. +
  6990. + curFlatBuffer++;
  6991. + pShInfo = skb_shinfo(pSkb);
  6992. + if (pShInfo->frag_list != NULL && pShInfo->nr_frags != 0) {
  6993. + EPRINTK("%s():"
  6994. + "Translation for a combination of frag_list "
  6995. + "and frags[] array not supported!\n", __FUNCTION__);
  6996. + return ICP_OCF_DRV_STATUS_FAIL;
  6997. + } else if (pShInfo->frag_list != NULL) {
  6998. + /*
  6999. + * Non linear skbuff supported through frag_list
  7000. + * Perform translation for each fragment (sk_buff)
  7001. + * in the frag_list of the first sk_buff.
  7002. + */
  7003. + for (pCurFrag = pShInfo->frag_list;
  7004. + pCurFrag != NULL; pCurFrag = pCurFrag->next) {
  7005. + icp_ocfDrvSingleSkBuffToFlatBuffer(pCurFrag,
  7006. + curFlatBuffer);
  7007. + curFlatBuffer++;
  7008. + bufferList->numBuffers++;
  7009. + }
  7010. + } else if (pShInfo->nr_frags != 0) {
  7011. + /*
  7012. + * Perform translation for each fragment in frags array
  7013. + * and add to the BufferList
  7014. + */
  7015. + for (i = 0; i < pShInfo->nr_frags; i++) {
  7016. + /* Get the page address and offset of this frag */
  7017. + skbuffPageAddr = (char *)pShInfo->frags[i].page;
  7018. + page_offset = pShInfo->frags[i].page_offset;
  7019. +
  7020. + /* Convert a pointer and length to a flat buffer */
  7021. + icp_ocfDrvPtrAndLenToFlatBuffer(skbuffPageAddr +
  7022. + page_offset,
  7023. + pShInfo->frags[i].size,
  7024. + curFlatBuffer);
  7025. + curFlatBuffer++;
  7026. + bufferList->numBuffers++;
  7027. + }
  7028. + } else {
  7029. + EPRINTK("%s():" "Could not recognize skbuff fragments!\n",
  7030. + __FUNCTION__);
  7031. + return ICP_OCF_DRV_STATUS_FAIL;
  7032. + }
  7033. +
  7034. + DPRINTK("%s(): Exit Point\n", __FUNCTION__);
  7035. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7036. +}
  7037. +
  7038. +/* Name : icp_ocfDrvBufferListToSkBuff
  7039. + *
  7040. + * Description : This function converts a Fredericksburg Scatter/Gather
  7041. + * (CpaBufferList) buffer format to socket buffer structure.
  7042. + */
  7043. +inline int
  7044. +icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList, struct sk_buff **skb)
  7045. +{
  7046. + DPRINTK("%s(): Entry Point\n", __FUNCTION__);
  7047. +
  7048. + /* Retrieve the orignal skbuff */
  7049. + *skb = (struct sk_buff *)bufferList->pUserData;
  7050. + if (NULL == *skb) {
  7051. + EPRINTK("%s():"
  7052. + "Error on converting from a BufferList. "
  7053. + "The BufferList does not contain an sk_buff.\n",
  7054. + __FUNCTION__);
  7055. + return ICP_OCF_DRV_STATUS_FAIL;
  7056. + }
  7057. + DPRINTK("%s(): Exit Point\n", __FUNCTION__);
  7058. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7059. +}
  7060. +
  7061. +/* Name : icp_ocfDrvPtrAndLenToBufferList
  7062. + *
  7063. + * Description : This function converts a "pointer and length" buffer
  7064. + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  7065. + *
  7066. + * This function assumes that the data passed in are valid.
  7067. + */
  7068. +inline void
  7069. +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  7070. + CpaBufferList * pBufferList)
  7071. +{
  7072. + pBufferList->numBuffers = 1;
  7073. + pBufferList->pBuffers->pData = pDataIn;
  7074. + pBufferList->pBuffers->dataLenInBytes = length;
  7075. +}
  7076. +
  7077. +/* Name : icp_ocfDrvBufferListToPtrAndLen
  7078. + *
  7079. + * Description : This function converts Fredericksburg Scatter/Gather Buffer
  7080. + * (CpaBufferList) format to a "pointer and length" buffer structure.
  7081. + *
  7082. + * This function assumes that the data passed in are valid.
  7083. + */
  7084. +inline void
  7085. +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  7086. + void **ppDataOut, uint32_t * pLength)
  7087. +{
  7088. + *ppDataOut = pBufferList->pBuffers->pData;
  7089. + *pLength = pBufferList->pBuffers->dataLenInBytes;
  7090. +}
  7091. +
  7092. +/* Name : icp_ocfDrvBufferListMemInfo
  7093. + *
  7094. + * Description : This function will set the number of flat buffers in
  7095. + * bufferlist, the size of memory to allocate for the pPrivateMetaData
  7096. + * member of the CpaBufferList.
  7097. + */
  7098. +int
  7099. +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  7100. + struct icp_drvBuffListInfo *buffListInfo)
  7101. +{
  7102. + buffListInfo->numBuffers = numBuffers;
  7103. +
  7104. + if (CPA_STATUS_SUCCESS !=
  7105. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  7106. + buffListInfo->numBuffers,
  7107. + &(buffListInfo->metaSize))) {
  7108. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  7109. + __FUNCTION__);
  7110. + return ICP_OCF_DRV_STATUS_FAIL;
  7111. + }
  7112. +
  7113. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7114. +}
  7115. +
  7116. +/* Name : icp_ocfDrvGetSkBuffFrags
  7117. + *
  7118. + * Description : This function will determine the number of
  7119. + * fragments in a socket buffer(sk_buff).
  7120. + */
  7121. +inline uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff * pSkb)
  7122. +{
  7123. + uint16_t numFrags = 0;
  7124. + struct sk_buff *pCurFrag = NULL;
  7125. + struct skb_shared_info *pShInfo = NULL;
  7126. +
  7127. + if (NULL == pSkb)
  7128. + return 0;
  7129. +
  7130. + numFrags = 1;
  7131. + if (0 == skb_is_nonlinear(pSkb)) {
  7132. + /* Linear buffer - it's a single skbuff */
  7133. + return numFrags;
  7134. + }
  7135. +
  7136. + pShInfo = skb_shinfo(pSkb);
  7137. + if (NULL != pShInfo->frag_list && 0 != pShInfo->nr_frags) {
  7138. + EPRINTK("%s(): Combination of frag_list "
  7139. + "and frags[] array not supported!\n", __FUNCTION__);
  7140. + return 0;
  7141. + } else if (0 != pShInfo->nr_frags) {
  7142. + numFrags += pShInfo->nr_frags;
  7143. + return numFrags;
  7144. + } else if (NULL != pShInfo->frag_list) {
  7145. + for (pCurFrag = pShInfo->frag_list;
  7146. + pCurFrag != NULL; pCurFrag = pCurFrag->next) {
  7147. + numFrags++;
  7148. + }
  7149. + return numFrags;
  7150. + } else {
  7151. + return 0;
  7152. + }
  7153. +}
  7154. +
  7155. +/* Name : icp_ocfDrvFreeFlatBuffer
  7156. + *
  7157. + * Description : This function will deallocate flat buffer.
  7158. + */
  7159. +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  7160. +{
  7161. + if (pFlatBuffer != NULL) {
  7162. + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  7163. + kmem_cache_free(drvFlatBuffer_zone, pFlatBuffer);
  7164. + }
  7165. +}
  7166. +
  7167. +/* Name : icp_ocfDrvAllocMetaData
  7168. + *
  7169. + * Description : This function will allocate memory for the
  7170. + * pPrivateMetaData member of CpaBufferList.
  7171. + */
  7172. +inline int
  7173. +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  7174. + const struct icp_drvOpData *pOpData)
  7175. +{
  7176. + Cpa32U metaSize = 0;
  7177. +
  7178. + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS){
  7179. + void *pOpDataStartAddr = (void *)pOpData;
  7180. +
  7181. + if (0 == defBuffListInfo.metaSize) {
  7182. + pBufferList->pPrivateMetaData = NULL;
  7183. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7184. + }
  7185. + /*
  7186. + * The meta data allocation has been included as part of the
  7187. + * op data. It has been pre-allocated in memory just after the
  7188. + * icp_drvOpData structure.
  7189. + */
  7190. + pBufferList->pPrivateMetaData = pOpDataStartAddr +
  7191. + sizeof(struct icp_drvOpData);
  7192. + } else {
  7193. + if (CPA_STATUS_SUCCESS !=
  7194. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  7195. + pBufferList->numBuffers,
  7196. + &metaSize)) {
  7197. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  7198. + __FUNCTION__);
  7199. + return ICP_OCF_DRV_STATUS_FAIL;
  7200. + }
  7201. +
  7202. + if (0 == metaSize) {
  7203. + pBufferList->pPrivateMetaData = NULL;
  7204. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7205. + }
  7206. +
  7207. + pBufferList->pPrivateMetaData = kmalloc(metaSize, GFP_ATOMIC);
  7208. + }
  7209. + if (NULL == pBufferList->pPrivateMetaData) {
  7210. + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  7211. + __FUNCTION__);
  7212. + return ICP_OCF_DRV_STATUS_FAIL;
  7213. + }
  7214. +
  7215. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7216. +}
  7217. +
  7218. +/* Name : icp_ocfDrvFreeMetaData
  7219. + *
  7220. + * Description : This function will deallocate pPrivateMetaData memory.
  7221. + */
  7222. +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  7223. +{
  7224. + if (NULL == pBufferList->pPrivateMetaData) {
  7225. + return;
  7226. + }
  7227. +
  7228. + /*
  7229. + * Only free the meta data if the BufferList has more than
  7230. + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  7231. + * Otherwise, the meta data shall be freed when the icp_drvOpData is
  7232. + * freed.
  7233. + */
  7234. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers){
  7235. + kfree(pBufferList->pPrivateMetaData);
  7236. + }
  7237. +}
  7238. +
  7239. +module_init(icp_ocfDrvInit);
  7240. +module_exit(icp_ocfDrvExit);
  7241. +MODULE_LICENSE("Dual BSD/GPL");
  7242. +MODULE_AUTHOR("Intel");
  7243. +MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  7244. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.29.1/crypto/ocf/ep80579/icp_ocf.h
  7245. --- linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
  7246. +++ linux-2.6.29.1/crypto/ocf/ep80579/icp_ocf.h 2009-04-20 20:01:21.436552036 +0200
  7247. @@ -0,0 +1,363 @@
  7248. +/***************************************************************************
  7249. + *
  7250. + * This file is provided under a dual BSD/GPLv2 license. When using or
  7251. + * redistributing this file, you may do so under either license.
  7252. + *
  7253. + * GPL LICENSE SUMMARY
  7254. + *
  7255. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  7256. + *
  7257. + * This program is free software; you can redistribute it and/or modify
  7258. + * it under the terms of version 2 of the GNU General Public License as
  7259. + * published by the Free Software Foundation.
  7260. + *
  7261. + * This program is distributed in the hope that it will be useful, but
  7262. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  7263. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  7264. + * General Public License for more details.
  7265. + *
  7266. + * You should have received a copy of the GNU General Public License
  7267. + * along with this program; if not, write to the Free Software
  7268. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  7269. + * The full GNU General Public License is included in this distribution
  7270. + * in the file called LICENSE.GPL.
  7271. + *
  7272. + * Contact Information:
  7273. + * Intel Corporation
  7274. + *
  7275. + * BSD LICENSE
  7276. + *
  7277. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  7278. + * All rights reserved.
  7279. + *
  7280. + * Redistribution and use in source and binary forms, with or without
  7281. + * modification, are permitted provided that the following conditions
  7282. + * are met:
  7283. + *
  7284. + * * Redistributions of source code must retain the above copyright
  7285. + * notice, this list of conditions and the following disclaimer.
  7286. + * * Redistributions in binary form must reproduce the above copyright
  7287. + * notice, this list of conditions and the following disclaimer in
  7288. + * the documentation and/or other materials provided with the
  7289. + * distribution.
  7290. + * * Neither the name of Intel Corporation nor the names of its
  7291. + * contributors may be used to endorse or promote products derived
  7292. + * from this software without specific prior written permission.
  7293. + *
  7294. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  7295. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7296. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  7297. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7298. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  7299. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  7300. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  7301. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  7302. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7303. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  7304. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7305. + *
  7306. + *
  7307. + * version: Security.L.1.0.130
  7308. + *
  7309. + ***************************************************************************/
  7310. +
  7311. +/*
  7312. + * OCF drv driver header file for the Intel ICP processor.
  7313. + */
  7314. +
  7315. +#ifndef ICP_OCF_H
  7316. +#define ICP_OCF_H
  7317. +
  7318. +#include <linux/crypto.h>
  7319. +#include <linux/delay.h>
  7320. +#include <linux/skbuff.h>
  7321. +
  7322. +#include "cryptodev.h"
  7323. +#include "uio.h"
  7324. +
  7325. +#include "cpa.h"
  7326. +#include "cpa_cy_im.h"
  7327. +#include "cpa_cy_sym.h"
  7328. +#include "cpa_cy_rand.h"
  7329. +#include "cpa_cy_dh.h"
  7330. +#include "cpa_cy_rsa.h"
  7331. +#include "cpa_cy_ln.h"
  7332. +#include "cpa_cy_common.h"
  7333. +#include "cpa_cy_dsa.h"
  7334. +
  7335. +#define NUM_BITS_IN_BYTE (8)
  7336. +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
  7337. +#define INVALID_DRIVER_ID (-1)
  7338. +#define RETURN_RAND_NUM_GEN_FAILED (-1)
  7339. +
  7340. +/*This is define means only one operation can be chained to another
  7341. +(resulting in one chain of two operations)*/
  7342. +#define MAX_NUM_OF_CHAINED_OPS (1)
  7343. +/*This is the max block cipher initialisation vector*/
  7344. +#define MAX_IV_LEN_IN_BYTES (20)
  7345. +/*This is used to check whether the OCF to this driver session limit has
  7346. + been disabled*/
  7347. +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
  7348. +
  7349. +/*OCF values mapped here*/
  7350. +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
  7351. +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
  7352. +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
  7353. +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
  7354. +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
  7355. +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
  7356. +
  7357. +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
  7358. +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
  7359. +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
  7360. +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
  7361. +#define ICP_OCF_DRV_STATUS_FAIL (1)
  7362. +
  7363. +/*Turn on/off debug options*/
  7364. +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
  7365. +#define ICP_OCF_PRINT_KERN_ALERT (1)
  7366. +#define ICP_OCF_PRINT_KERN_ERRS (1)
  7367. +
  7368. +/*DSA Prime Q size in bytes (as defined in the standard) */
  7369. +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
  7370. +
  7371. +/*MACRO DEFINITIONS*/
  7372. +
  7373. +#define BITS_TO_BYTES(bytes, bits) \
  7374. + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
  7375. +
  7376. +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
  7377. + kmem_cache_create(cache_ID, sizeof(cache_name),0, \
  7378. + SLAB_HWCACHE_ALIGN, NULL, NULL);
  7379. +
  7380. +#define ICP_CACHE_NULL_CHECK(slab_zone) \
  7381. +{ \
  7382. + if(NULL == slab_zone){ \
  7383. + icp_ocfDrvFreeCaches(); \
  7384. + EPRINTK("%s() line %d: Not enough memory!\n", \
  7385. + __FUNCTION__, __LINE__); \
  7386. + return ENOMEM; \
  7387. + } \
  7388. +}
  7389. +
  7390. +#define ICP_CACHE_DESTROY(slab_zone) \
  7391. +{ \
  7392. + if(NULL != slab_zone){ \
  7393. + kmem_cache_destroy(slab_zone); \
  7394. + slab_zone = NULL; \
  7395. + } \
  7396. +}
  7397. +
  7398. +#define ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(alg) \
  7399. +{ \
  7400. + if(OCF_REGISTRATION_STATUS_SUCCESS == \
  7401. + crypto_register(icp_ocfDrvDriverId, \
  7402. + alg, \
  7403. + 0, \
  7404. + 0)) { \
  7405. + ocfStatus++; \
  7406. + } \
  7407. +}
  7408. +
  7409. +#define ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(alg) \
  7410. +{ \
  7411. + if(OCF_REGISTRATION_STATUS_SUCCESS == \
  7412. + crypto_kregister(icp_ocfDrvDriverId, \
  7413. + alg, \
  7414. + 0)){ \
  7415. + ocfStatus++; \
  7416. + } \
  7417. +}
  7418. +
  7419. +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  7420. +#define DPRINTK(args...) \
  7421. +{ \
  7422. + printk(args); \
  7423. +}
  7424. +
  7425. +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  7426. +
  7427. +#define DPRINTK(args...)
  7428. +
  7429. +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  7430. +
  7431. +#if ICP_OCF_PRINT_KERN_ALERT == 1
  7432. +#define APRINTK(args...) \
  7433. +{ \
  7434. + printk(KERN_ALERT args); \
  7435. +}
  7436. +
  7437. +#else //ICP_OCF_PRINT_KERN_ALERT == 1
  7438. +
  7439. +#define APRINTK(args...)
  7440. +
  7441. +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
  7442. +
  7443. +#if ICP_OCF_PRINT_KERN_ERRS == 1
  7444. +#define EPRINTK(args...) \
  7445. +{ \
  7446. + printk(KERN_ERR args); \
  7447. +}
  7448. +
  7449. +#else //ICP_OCF_PRINT_KERN_ERRS == 1
  7450. +
  7451. +#define EPRINTK(args...)
  7452. +
  7453. +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
  7454. +
  7455. +#define IPRINTK(args...) \
  7456. +{ \
  7457. + printk(KERN_INFO args); \
  7458. +}
  7459. +
  7460. +/*END OF MACRO DEFINITIONS*/
  7461. +
  7462. +typedef enum {
  7463. + ICP_OCF_DRV_ALG_CIPHER = 0,
  7464. + ICP_OCF_DRV_ALG_HASH
  7465. +} icp_ocf_drv_alg_type_t;
  7466. +
  7467. +/* These are all defined in icp_common.c */
  7468. +extern atomic_t lac_session_failed_dereg_count;
  7469. +extern atomic_t icp_ocfDrvIsExiting;
  7470. +extern atomic_t num_ocf_to_drv_registered_sessions;
  7471. +
  7472. +/*These are use inputs used in icp_sym.c and icp_common.c
  7473. + They are instantiated in icp_common.c*/
  7474. +extern int max_sessions;
  7475. +
  7476. +extern int32_t icp_ocfDrvDriverId;
  7477. +extern struct list_head icp_ocfDrvGlobalSymListHead;
  7478. +extern struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
  7479. +extern struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
  7480. +extern spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  7481. +extern rwlock_t icp_kmem_cache_destroy_alloc_lock;
  7482. +
  7483. +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
  7484. +extern struct kmem_cache *drvSessionData_zone;
  7485. +extern struct kmem_cache *drvOpData_zone;
  7486. +
  7487. +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
  7488. +extern struct kmem_cache *drvDH_zone;
  7489. +extern struct kmem_cache *drvLnModExp_zone;
  7490. +extern struct kmem_cache *drvRSADecrypt_zone;
  7491. +extern struct kmem_cache *drvRSAPrivateKey_zone;
  7492. +extern struct kmem_cache *drvDSARSSign_zone;
  7493. +extern struct kmem_cache *drvDSARSSignKValue_zone;
  7494. +extern struct kmem_cache *drvDSAVerify_zone;
  7495. +
  7496. +/*Slab zones for flatbuffers and bufferlist*/
  7497. +extern struct kmem_cache *drvFlatBuffer_zone;
  7498. +
  7499. +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
  7500. +
  7501. +struct icp_drvBuffListInfo {
  7502. + Cpa16U numBuffers;
  7503. + Cpa32U metaSize;
  7504. + Cpa32U metaOffset;
  7505. + Cpa32U buffListSize;
  7506. +};
  7507. +extern struct icp_drvBuffListInfo defBuffListInfo;
  7508. +
  7509. +/*
  7510. +* This struct is used to keep a reference to the relevant node in the list
  7511. +* of sessionData structs, to the buffer type required by OCF and to the OCF
  7512. +* provided crp struct that needs to be returned. All this info is needed in
  7513. +* the callback function.
  7514. +*
  7515. +* IV can sometimes be stored in non-contiguous memory (e.g. skbuff
  7516. +* linked/frag list, therefore a contiguous memory space for the IV data must be
  7517. +* created and passed to LAC
  7518. +*
  7519. +*/
  7520. +struct icp_drvOpData {
  7521. + CpaCySymOpData lacOpData;
  7522. + uint32_t digestSizeInBytes;
  7523. + struct cryptop *crp;
  7524. + uint8_t bufferType;
  7525. + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
  7526. + uint16_t numBufferListArray;
  7527. + CpaBufferList srcBuffer;
  7528. + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
  7529. + CpaBoolean verifyResult;
  7530. +};
  7531. +/*Values used to derisk chances of performs being called against
  7532. +deregistered sessions (for which the slab page has been reclaimed)
  7533. +This is not a fix - since page frames are reclaimed from a slab, one cannot
  7534. +rely on that memory not being re-used by another app.*/
  7535. +typedef enum {
  7536. + ICP_SESSION_INITIALISED = 0x5C5C5C,
  7537. + ICP_SESSION_RUNNING = 0x005C00,
  7538. + ICP_SESSION_DEREGISTERED = 0xC5C5C5
  7539. +} usage_derisk;
  7540. +
  7541. +/*
  7542. +This is the OCF<->OCF_DRV session object:
  7543. +
  7544. +1.The first member is a listNode. These session objects are added to a linked
  7545. + list in order to make it easier to remove them all at session exit time.
  7546. +2.The second member is used to give the session object state and derisk the
  7547. + possibility of OCF batch calls executing against a deregistered session (as
  7548. + described above).
  7549. +3.The third member is a LAC<->OCF_DRV session handle (initialised with the first
  7550. + perform request for that session).
  7551. +4.The fourth is the LAC session context. All the parameters for this structure
  7552. + are only known when the first perform request for this session occurs. That is
  7553. + why the OCF Tolapai Driver only registers a new LAC session at perform time
  7554. +*/
  7555. +struct icp_drvSessionData {
  7556. + struct list_head listNode;
  7557. + usage_derisk inUse;
  7558. + CpaCySymSessionCtx sessHandle;
  7559. + CpaCySymSessionSetupData lacSessCtx;
  7560. +};
  7561. +
  7562. +/* This struct is required for deferred session
  7563. + deregistration as a work queue function can
  7564. + only have one argument*/
  7565. +struct icp_ocfDrvFreeLacSession {
  7566. + CpaCySymSessionCtx sessionToDeregister;
  7567. + struct work_struct work;
  7568. +};
  7569. +
  7570. +int icp_ocfDrvNewSession(device_t dev, uint32_t * sild, struct cryptoini *cri);
  7571. +
  7572. +int icp_ocfDrvFreeLACSession(device_t dev, uint64_t sid);
  7573. +
  7574. +int icp_ocfDrvSymProcess(device_t dev, struct cryptop *crp, int hint);
  7575. +
  7576. +int icp_ocfDrvPkeProcess(device_t dev, struct cryptkop *krp, int hint);
  7577. +
  7578. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
  7579. +
  7580. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
  7581. +
  7582. +int icp_ocfDrvSkBuffToBufferList(struct sk_buff *skb,
  7583. + CpaBufferList * bufferList);
  7584. +
  7585. +int icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList,
  7586. + struct sk_buff **skb);
  7587. +
  7588. +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  7589. + CpaFlatBuffer * pFlatBuffer);
  7590. +
  7591. +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  7592. + CpaBufferList * pBufferList);
  7593. +
  7594. +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  7595. + void **ppDataOut, uint32_t * pLength);
  7596. +
  7597. +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  7598. + struct icp_drvBuffListInfo *buffListInfo);
  7599. +
  7600. +uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff *pSkb);
  7601. +
  7602. +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
  7603. +
  7604. +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  7605. + const struct icp_drvOpData *pOpData);
  7606. +
  7607. +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
  7608. +
  7609. +#endif
  7610. +/* ICP_OCF_H */
  7611. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.29.1/crypto/ocf/ep80579/icp_sym.c
  7612. --- linux-2.6.29.1.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
  7613. +++ linux-2.6.29.1/crypto/ocf/ep80579/icp_sym.c 2009-04-20 20:01:21.464554764 +0200
  7614. @@ -0,0 +1,1382 @@
  7615. +/***************************************************************************
  7616. + *
  7617. + * This file is provided under a dual BSD/GPLv2 license. When using or
  7618. + * redistributing this file, you may do so under either license.
  7619. + *
  7620. + * GPL LICENSE SUMMARY
  7621. + *
  7622. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  7623. + *
  7624. + * This program is free software; you can redistribute it and/or modify
  7625. + * it under the terms of version 2 of the GNU General Public License as
  7626. + * published by the Free Software Foundation.
  7627. + *
  7628. + * This program is distributed in the hope that it will be useful, but
  7629. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  7630. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  7631. + * General Public License for more details.
  7632. + *
  7633. + * You should have received a copy of the GNU General Public License
  7634. + * along with this program; if not, write to the Free Software
  7635. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  7636. + * The full GNU General Public License is included in this distribution
  7637. + * in the file called LICENSE.GPL.
  7638. + *
  7639. + * Contact Information:
  7640. + * Intel Corporation
  7641. + *
  7642. + * BSD LICENSE
  7643. + *
  7644. + * Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
  7645. + * All rights reserved.
  7646. + *
  7647. + * Redistribution and use in source and binary forms, with or without
  7648. + * modification, are permitted provided that the following conditions
  7649. + * are met:
  7650. + *
  7651. + * * Redistributions of source code must retain the above copyright
  7652. + * notice, this list of conditions and the following disclaimer.
  7653. + * * Redistributions in binary form must reproduce the above copyright
  7654. + * notice, this list of conditions and the following disclaimer in
  7655. + * the documentation and/or other materials provided with the
  7656. + * distribution.
  7657. + * * Neither the name of Intel Corporation nor the names of its
  7658. + * contributors may be used to endorse or promote products derived
  7659. + * from this software without specific prior written permission.
  7660. + *
  7661. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  7662. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7663. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  7664. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7665. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  7666. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  7667. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  7668. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  7669. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7670. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  7671. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7672. + *
  7673. + *
  7674. + * version: Security.L.1.0.130
  7675. + *
  7676. + ***************************************************************************/
  7677. +/*
  7678. + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
  7679. + * cryptography.
  7680. + *
  7681. + * This driver requires the ICP Access Library that is available from Intel in
  7682. + * order to operate.
  7683. + */
  7684. +
  7685. +#include "icp_ocf.h"
  7686. +
  7687. +/*This is the call back function for all symmetric cryptographic processes.
  7688. + Its main functionality is to free driver crypto operation structure and to
  7689. + call back to OCF*/
  7690. +static void
  7691. +icp_ocfDrvSymCallBack(void *callbackTag,
  7692. + CpaStatus status,
  7693. + const CpaCySymOp operationType,
  7694. + void *pOpData,
  7695. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  7696. +
  7697. +/*This function is used to extract crypto processing information from the OCF
  7698. + inputs, so as that it may be passed onto LAC*/
  7699. +static int
  7700. +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  7701. + struct cryptodesc *crp_desc);
  7702. +
  7703. +/*This function checks whether the crp_desc argument pertains to a digest or a
  7704. + cipher operation*/
  7705. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  7706. +
  7707. +/*This function copies all the passed in session context information and stores
  7708. + it in a LAC context structure*/
  7709. +static int
  7710. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  7711. + CpaCySymSessionSetupData * lacSessCtx);
  7712. +
  7713. +/*This top level function is used to find a pointer to where a digest is
  7714. + stored/needs to be inserted. */
  7715. +static uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  7716. + struct cryptodesc *crp_desc);
  7717. +
  7718. +/*This function is called when a digest pointer has to be found within a
  7719. + SKBUFF.*/
  7720. +static inline uint8_t *icp_ocfDrvSkbuffDigestPointerFind(struct icp_drvOpData
  7721. + *drvOpData,
  7722. + int offsetInBytes,
  7723. + uint32_t
  7724. + digestSizeInBytes);
  7725. +
  7726. +/*The following two functions are called if the SKBUFF digest pointer is not
  7727. + positioned in the linear portion of the buffer (i.e. it is in a linked SKBUFF
  7728. + or page fragment).*/
  7729. +/*This function takes care of the page fragment case.*/
  7730. +static inline uint8_t *icp_ocfDrvDigestSkbNRFragsCheck(struct sk_buff *skb,
  7731. + struct skb_shared_info
  7732. + *skb_shared,
  7733. + int offsetInBytes,
  7734. + uint32_t
  7735. + digestSizeInBytes);
  7736. +
  7737. +/*This function takes care of the linked list case.*/
  7738. +static inline uint8_t *icp_ocfDrvDigestSkbFragListCheck(struct sk_buff *skb,
  7739. + struct skb_shared_info
  7740. + *skb_shared,
  7741. + int offsetInBytes,
  7742. + uint32_t
  7743. + digestSizeInBytes);
  7744. +
  7745. +/*This function is used to free an OCF->OCF_DRV session object*/
  7746. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  7747. +
  7748. +/*max IOV buffs supported in a UIO structure*/
  7749. +#define NUM_IOV_SUPPORTED (1)
  7750. +
  7751. +/* Name : icp_ocfDrvSymCallBack
  7752. + *
  7753. + * Description : When this function returns it signifies that the LAC
  7754. + * component has completed the relevant symmetric operation.
  7755. + *
  7756. + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  7757. + * object was passed to LAC for the cryptographic processing and contains all
  7758. + * the relevant information for cleaning up buffer handles etc. so that the
  7759. + * OCF Tolapai Driver portion of this crypto operation can be fully completed.
  7760. + */
  7761. +static void
  7762. +icp_ocfDrvSymCallBack(void *callbackTag,
  7763. + CpaStatus status,
  7764. + const CpaCySymOp operationType,
  7765. + void *pOpData,
  7766. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  7767. +{
  7768. + struct cryptop *crp = NULL;
  7769. + struct icp_drvOpData *temp_drvOpData =
  7770. + (struct icp_drvOpData *)callbackTag;
  7771. + uint64_t *tempBasePtr = NULL;
  7772. + uint32_t tempLen = 0;
  7773. +
  7774. + if (NULL == temp_drvOpData) {
  7775. + DPRINTK("%s(): The callback from the LAC component"
  7776. + " has failed due to Null userOpaque data"
  7777. + "(status == %d).\n", __FUNCTION__, status);
  7778. + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  7779. + return;
  7780. + }
  7781. +
  7782. + crp = temp_drvOpData->crp;
  7783. + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  7784. +
  7785. + if (NULL == pOpData) {
  7786. + DPRINTK("%s(): The callback from the LAC component"
  7787. + " has failed due to Null Symmetric Op data"
  7788. + "(status == %d).\n", __FUNCTION__, status);
  7789. + crp->crp_etype = ECANCELED;
  7790. + crypto_done(crp);
  7791. + return;
  7792. + }
  7793. +
  7794. + if (NULL == pDstBuffer) {
  7795. + DPRINTK("%s(): The callback from the LAC component"
  7796. + " has failed due to Null Dst Bufferlist data"
  7797. + "(status == %d).\n", __FUNCTION__, status);
  7798. + crp->crp_etype = ECANCELED;
  7799. + crypto_done(crp);
  7800. + return;
  7801. + }
  7802. +
  7803. + if (CPA_STATUS_SUCCESS == status) {
  7804. +
  7805. + if (temp_drvOpData->bufferType == CRYPTO_F_SKBUF) {
  7806. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7807. + icp_ocfDrvBufferListToSkBuff(pDstBuffer,
  7808. + (struct sk_buff **)
  7809. + &(crp->crp_buf))) {
  7810. + EPRINTK("%s(): BufferList to SkBuff "
  7811. + "conversion error.\n", __FUNCTION__);
  7812. + crp->crp_etype = EPERM;
  7813. + }
  7814. + } else {
  7815. + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  7816. + (void **)&tempBasePtr,
  7817. + &tempLen);
  7818. + crp->crp_olen = (int)tempLen;
  7819. + }
  7820. +
  7821. + } else {
  7822. + DPRINTK("%s(): The callback from the LAC component has failed"
  7823. + "(status == %d).\n", __FUNCTION__, status);
  7824. +
  7825. + crp->crp_etype = ECANCELED;
  7826. + }
  7827. +
  7828. + if (temp_drvOpData->numBufferListArray >
  7829. + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  7830. + kfree(pDstBuffer->pBuffers);
  7831. + }
  7832. + icp_ocfDrvFreeMetaData(pDstBuffer);
  7833. + kmem_cache_free(drvOpData_zone, temp_drvOpData);
  7834. +
  7835. + /* Invoke the OCF callback function */
  7836. + crypto_done(crp);
  7837. +
  7838. + return;
  7839. +}
  7840. +
  7841. +/* Name : icp_ocfDrvNewSession
  7842. + *
  7843. + * Description : This function will create a new Driver<->OCF session
  7844. + *
  7845. + * Notes : LAC session registration happens during the first perform call.
  7846. + * That is the first time we know all information about a given session.
  7847. + */
  7848. +int icp_ocfDrvNewSession(device_t dev, uint32_t * sid, struct cryptoini *cri)
  7849. +{
  7850. + struct icp_drvSessionData *sessionData = NULL;
  7851. + uint32_t delete_session = 0;
  7852. +
  7853. + /* The SID passed in should be our driver ID. We can return the */
  7854. + /* local ID (LID) which is a unique identifier which we can use */
  7855. + /* to differentiate between the encrypt/decrypt LAC session handles */
  7856. + if (NULL == sid) {
  7857. + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  7858. + __FUNCTION__);
  7859. + return EINVAL;
  7860. + }
  7861. +
  7862. + if (NULL == cri) {
  7863. + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  7864. + __FUNCTION__);
  7865. + return EINVAL;
  7866. + }
  7867. +
  7868. + if (icp_ocfDrvDriverId != *sid) {
  7869. + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  7870. + __FUNCTION__);
  7871. + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  7872. + return EINVAL;
  7873. + }
  7874. +
  7875. + sessionData = kmem_cache_zalloc(drvSessionData_zone, GFP_ATOMIC);
  7876. + if (NULL == sessionData) {
  7877. + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  7878. + return ENOMEM;
  7879. + }
  7880. +
  7881. + /*ENTER CRITICAL SECTION */
  7882. + spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7883. + /*put this check in the spinlock so no new sessions can be added to the
  7884. + linked list when we are exiting */
  7885. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  7886. + delete_session++;
  7887. +
  7888. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  7889. + if (atomic_read(&num_ocf_to_drv_registered_sessions) >=
  7890. + (max_sessions -
  7891. + atomic_read(&lac_session_failed_dereg_count))) {
  7892. + delete_session++;
  7893. + } else {
  7894. + atomic_inc(&num_ocf_to_drv_registered_sessions);
  7895. + /* Add to session data linked list */
  7896. + list_add(&(sessionData->listNode),
  7897. + &icp_ocfDrvGlobalSymListHead);
  7898. + }
  7899. +
  7900. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  7901. + list_add(&(sessionData->listNode),
  7902. + &icp_ocfDrvGlobalSymListHead);
  7903. + }
  7904. +
  7905. + sessionData->inUse = ICP_SESSION_INITIALISED;
  7906. +
  7907. + /*EXIT CRITICAL SECTION */
  7908. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  7909. +
  7910. + if (delete_session) {
  7911. + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  7912. + kmem_cache_free(drvSessionData_zone, sessionData);
  7913. + return EPERM;
  7914. + }
  7915. +
  7916. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7917. + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  7918. + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  7919. + icp_ocfDrvFreeOCFSession(sessionData);
  7920. + return EINVAL;
  7921. + }
  7922. +
  7923. + if (cri->cri_next) {
  7924. + if (cri->cri_next->cri_next != NULL) {
  7925. + DPRINTK("%s():only two chained algorithms supported\n",
  7926. + __FUNCTION__);
  7927. + icp_ocfDrvFreeOCFSession(sessionData);
  7928. + return EPERM;
  7929. + }
  7930. +
  7931. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  7932. + icp_ocfDrvAlgorithmSetup(cri->cri_next,
  7933. + &(sessionData->lacSessCtx))) {
  7934. + DPRINTK("%s():second algorithm not supported\n",
  7935. + __FUNCTION__);
  7936. + icp_ocfDrvFreeOCFSession(sessionData);
  7937. + return EINVAL;
  7938. + }
  7939. +
  7940. + sessionData->lacSessCtx.symOperation =
  7941. + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  7942. + }
  7943. +
  7944. + *sid = (uint32_t) sessionData;
  7945. +
  7946. + return ICP_OCF_DRV_STATUS_SUCCESS;
  7947. +}
  7948. +
  7949. +/* Name : icp_ocfDrvAlgorithmSetup
  7950. + *
  7951. + * Description : This function builds the session context data from the
  7952. + * information supplied through OCF. Algorithm chain order and whether the
  7953. + * session is Encrypt/Decrypt can only be found out at perform time however, so
  7954. + * the session is registered with LAC at that time.
  7955. + */
  7956. +static int
  7957. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  7958. + CpaCySymSessionSetupData * lacSessCtx)
  7959. +{
  7960. +
  7961. + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  7962. +
  7963. + switch (cri->cri_alg) {
  7964. +
  7965. + case CRYPTO_NULL_CBC:
  7966. + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  7967. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7968. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7969. + CPA_CY_SYM_CIPHER_NULL;
  7970. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7971. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7972. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7973. + break;
  7974. +
  7975. + case CRYPTO_DES_CBC:
  7976. + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  7977. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7978. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7979. + CPA_CY_SYM_CIPHER_DES_CBC;
  7980. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7981. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7982. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7983. + break;
  7984. +
  7985. + case CRYPTO_3DES_CBC:
  7986. + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  7987. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7988. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7989. + CPA_CY_SYM_CIPHER_3DES_CBC;
  7990. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  7991. + cri->cri_klen / NUM_BITS_IN_BYTE;
  7992. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  7993. + break;
  7994. +
  7995. + case CRYPTO_AES_CBC:
  7996. + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  7997. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  7998. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  7999. + CPA_CY_SYM_CIPHER_AES_CBC;
  8000. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  8001. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8002. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  8003. + break;
  8004. +
  8005. + case CRYPTO_ARC4:
  8006. + DPRINTK("%s(): ARC4\n", __FUNCTION__);
  8007. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  8008. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  8009. + CPA_CY_SYM_CIPHER_ARC4;
  8010. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  8011. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8012. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  8013. + break;
  8014. +
  8015. + case CRYPTO_SHA1:
  8016. + DPRINTK("%s(): SHA1\n", __FUNCTION__);
  8017. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8018. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  8019. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  8020. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8021. + (cri->cri_mlen ?
  8022. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  8023. +
  8024. + break;
  8025. +
  8026. + case CRYPTO_SHA1_HMAC:
  8027. + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  8028. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8029. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  8030. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  8031. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8032. + (cri->cri_mlen ?
  8033. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  8034. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  8035. + cri->cri_key;
  8036. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  8037. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8038. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  8039. +
  8040. + break;
  8041. +
  8042. + case CRYPTO_SHA2_256:
  8043. + DPRINTK("%s(): SHA256\n", __FUNCTION__);
  8044. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8045. + lacSessCtx->hashSetupData.hashAlgorithm =
  8046. + CPA_CY_SYM_HASH_SHA256;
  8047. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  8048. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8049. + (cri->cri_mlen ?
  8050. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  8051. +
  8052. + break;
  8053. +
  8054. + case CRYPTO_SHA2_256_HMAC:
  8055. + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  8056. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8057. + lacSessCtx->hashSetupData.hashAlgorithm =
  8058. + CPA_CY_SYM_HASH_SHA256;
  8059. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  8060. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8061. + (cri->cri_mlen ?
  8062. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  8063. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  8064. + cri->cri_key;
  8065. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  8066. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8067. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  8068. +
  8069. + break;
  8070. +
  8071. + case CRYPTO_SHA2_384:
  8072. + DPRINTK("%s(): SHA384\n", __FUNCTION__);
  8073. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8074. + lacSessCtx->hashSetupData.hashAlgorithm =
  8075. + CPA_CY_SYM_HASH_SHA384;
  8076. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  8077. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8078. + (cri->cri_mlen ?
  8079. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  8080. +
  8081. + break;
  8082. +
  8083. + case CRYPTO_SHA2_384_HMAC:
  8084. + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  8085. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8086. + lacSessCtx->hashSetupData.hashAlgorithm =
  8087. + CPA_CY_SYM_HASH_SHA384;
  8088. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  8089. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8090. + (cri->cri_mlen ?
  8091. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  8092. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  8093. + cri->cri_key;
  8094. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  8095. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8096. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  8097. +
  8098. + break;
  8099. +
  8100. + case CRYPTO_SHA2_512:
  8101. + DPRINTK("%s(): SHA512\n", __FUNCTION__);
  8102. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8103. + lacSessCtx->hashSetupData.hashAlgorithm =
  8104. + CPA_CY_SYM_HASH_SHA512;
  8105. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  8106. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8107. + (cri->cri_mlen ?
  8108. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  8109. +
  8110. + break;
  8111. +
  8112. + case CRYPTO_SHA2_512_HMAC:
  8113. + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  8114. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8115. + lacSessCtx->hashSetupData.hashAlgorithm =
  8116. + CPA_CY_SYM_HASH_SHA512;
  8117. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  8118. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8119. + (cri->cri_mlen ?
  8120. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  8121. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  8122. + cri->cri_key;
  8123. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  8124. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8125. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  8126. +
  8127. + break;
  8128. +
  8129. + case CRYPTO_MD5:
  8130. + DPRINTK("%s(): MD5\n", __FUNCTION__);
  8131. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8132. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  8133. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  8134. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8135. + (cri->cri_mlen ?
  8136. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  8137. +
  8138. + break;
  8139. +
  8140. + case CRYPTO_MD5_HMAC:
  8141. + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  8142. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  8143. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  8144. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  8145. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  8146. + (cri->cri_mlen ?
  8147. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  8148. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  8149. + cri->cri_key;
  8150. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  8151. + cri->cri_klen / NUM_BITS_IN_BYTE;
  8152. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  8153. +
  8154. + break;
  8155. +
  8156. + default:
  8157. + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  8158. + return ICP_OCF_DRV_STATUS_FAIL;
  8159. + }
  8160. +
  8161. + return ICP_OCF_DRV_STATUS_SUCCESS;
  8162. +}
  8163. +
  8164. +/* Name : icp_ocfDrvFreeOCFSession
  8165. + *
  8166. + * Description : This function deletes all existing Session data representing
  8167. + * the Cryptographic session established between OCF and this driver. This
  8168. + * also includes freeing the memory allocated for the session context. The
  8169. + * session object is also removed from the session linked list.
  8170. + */
  8171. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  8172. +{
  8173. +
  8174. + sessionData->inUse = ICP_SESSION_DEREGISTERED;
  8175. +
  8176. + /*ENTER CRITICAL SECTION */
  8177. + spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  8178. +
  8179. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  8180. + /*If the Driver is exiting, allow that process to
  8181. + handle any deletions */
  8182. + /*EXIT CRITICAL SECTION */
  8183. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  8184. + return;
  8185. + }
  8186. +
  8187. + atomic_dec(&num_ocf_to_drv_registered_sessions);
  8188. +
  8189. + list_del(&(sessionData->listNode));
  8190. +
  8191. + /*EXIT CRITICAL SECTION */
  8192. + spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
  8193. +
  8194. + if (NULL != sessionData->sessHandle) {
  8195. + kfree(sessionData->sessHandle);
  8196. + }
  8197. + kmem_cache_free(drvSessionData_zone, sessionData);
  8198. +}
  8199. +
  8200. +/* Name : icp_ocfDrvFreeLACSession
  8201. + *
  8202. + * Description : This attempts to deregister a LAC session. If it fails, the
  8203. + * deregistation retry function is called.
  8204. + */
  8205. +int icp_ocfDrvFreeLACSession(device_t dev, uint64_t sid)
  8206. +{
  8207. + CpaCySymSessionCtx sessionToDeregister = NULL;
  8208. + struct icp_drvSessionData *sessionData = NULL;
  8209. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  8210. + int retval = 0;
  8211. +
  8212. + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  8213. + if (NULL == sessionData) {
  8214. + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  8215. + __FUNCTION__);
  8216. + return EINVAL;
  8217. + }
  8218. +
  8219. + sessionToDeregister = sessionData->sessHandle;
  8220. +
  8221. + if (ICP_SESSION_INITIALISED == sessionData->inUse) {
  8222. + DPRINTK("%s() Session not registered with LAC\n", __FUNCTION__);
  8223. + } else if (NULL == sessionData->sessHandle) {
  8224. + EPRINTK
  8225. + ("%s(): OCF Free session called with Null Session Handle.\n",
  8226. + __FUNCTION__);
  8227. + return EINVAL;
  8228. + } else {
  8229. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  8230. + sessionToDeregister);
  8231. + if (CPA_STATUS_RETRY == lacStatus) {
  8232. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  8233. + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  8234. + /* the retry function increments the
  8235. + dereg failed count */
  8236. + DPRINTK("%s(): LAC failed to deregister the "
  8237. + "session. (localSessionId= %p)\n",
  8238. + __FUNCTION__, sessionToDeregister);
  8239. + retval = EPERM;
  8240. + }
  8241. +
  8242. + } else if (CPA_STATUS_SUCCESS != lacStatus) {
  8243. + DPRINTK("%s(): LAC failed to deregister the session. "
  8244. + "localSessionId= %p, lacStatus = %d\n",
  8245. + __FUNCTION__, sessionToDeregister, lacStatus);
  8246. + atomic_inc(&lac_session_failed_dereg_count);
  8247. + retval = EPERM;
  8248. + }
  8249. + }
  8250. +
  8251. + icp_ocfDrvFreeOCFSession(sessionData);
  8252. + return retval;
  8253. +
  8254. +}
  8255. +
  8256. +/* Name : icp_ocfDrvAlgCheck
  8257. + *
  8258. + * Description : This function checks whether the cryptodesc argument pertains
  8259. + * to a sym or hash function
  8260. + */
  8261. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  8262. +{
  8263. +
  8264. + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  8265. + crp_desc->crd_alg == CRYPTO_AES_CBC ||
  8266. + crp_desc->crd_alg == CRYPTO_DES_CBC ||
  8267. + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  8268. + crp_desc->crd_alg == CRYPTO_ARC4) {
  8269. + return ICP_OCF_DRV_ALG_CIPHER;
  8270. + }
  8271. +
  8272. + return ICP_OCF_DRV_ALG_HASH;
  8273. +}
  8274. +
  8275. +/* Name : icp_ocfDrvSymProcess
  8276. + *
  8277. + * Description : This function will map symmetric functionality calls from OCF
  8278. + * to the LAC API. It will also allocate memory to store the session context.
  8279. + *
  8280. + * Notes: If it is the first perform call for a given session, then a LAC
  8281. + * session is registered. After the session is registered, no checks as
  8282. + * to whether session paramaters have changed (e.g. alg chain order) are
  8283. + * done.
  8284. + */
  8285. +int icp_ocfDrvSymProcess(device_t dev, struct cryptop *crp, int hint)
  8286. +{
  8287. + struct icp_drvSessionData *sessionData = NULL;
  8288. + struct icp_drvOpData *drvOpData = NULL;
  8289. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  8290. + Cpa32U sessionCtxSizeInBytes = 0;
  8291. + uint16_t numBufferListArray = 0;
  8292. +
  8293. + if (NULL == crp) {
  8294. + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  8295. + __FUNCTION__);
  8296. + return EINVAL;
  8297. + }
  8298. +
  8299. + if (NULL == crp->crp_desc) {
  8300. + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  8301. + "to crp\n", __FUNCTION__);
  8302. + crp->crp_etype = EINVAL;
  8303. + return EINVAL;
  8304. + }
  8305. +
  8306. + if (NULL == crp->crp_buf) {
  8307. + DPRINTK("%s(): Invalid input parameters, no buffer attached "
  8308. + "to crp\n", __FUNCTION__);
  8309. + crp->crp_etype = EINVAL;
  8310. + return EINVAL;
  8311. + }
  8312. +
  8313. + if (CPA_TRUE == atomic_read(&icp_ocfDrvIsExiting)) {
  8314. + crp->crp_etype = EFAULT;
  8315. + return EFAULT;
  8316. + }
  8317. +
  8318. + sessionData = (struct icp_drvSessionData *)
  8319. + (CRYPTO_SESID2LID(crp->crp_sid));
  8320. + if (NULL == sessionData) {
  8321. + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  8322. + __FUNCTION__);
  8323. + crp->crp_etype = EINVAL;
  8324. + return EINVAL;
  8325. + }
  8326. +
  8327. +/*If we get a request against a deregisted session, cancel operation*/
  8328. + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  8329. + DPRINTK("%s(): Session ID %d was deregistered \n",
  8330. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  8331. + crp->crp_etype = EFAULT;
  8332. + return EFAULT;
  8333. + }
  8334. +
  8335. +/*If none of the session states are set, then the session structure was either
  8336. + not initialised properly or we are reading from a freed memory area (possible
  8337. + due to OCF batch mode not removing queued requests against deregistered
  8338. + sessions*/
  8339. + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  8340. + ICP_SESSION_RUNNING != sessionData->inUse) {
  8341. + DPRINTK("%s(): Session - ID %d - not properly initialised or "
  8342. + "memory freed back to the kernel \n",
  8343. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  8344. + crp->crp_etype = EINVAL;
  8345. + return EINVAL;
  8346. + }
  8347. +
  8348. + /*For the below checks, remember error checking is already done in LAC.
  8349. + We're not validating inputs subsequent to registration */
  8350. + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  8351. + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  8352. +
  8353. + if (NULL != crp->crp_desc->crd_next) {
  8354. + if (ICP_OCF_DRV_ALG_CIPHER ==
  8355. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  8356. +
  8357. + sessionData->lacSessCtx.algChainOrder =
  8358. + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  8359. +
  8360. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  8361. + sessionData->lacSessCtx.cipherSetupData.
  8362. + cipherDirection =
  8363. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  8364. + } else {
  8365. + sessionData->lacSessCtx.cipherSetupData.
  8366. + cipherDirection =
  8367. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  8368. + }
  8369. + } else {
  8370. + sessionData->lacSessCtx.algChainOrder =
  8371. + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  8372. +
  8373. + if (crp->crp_desc->crd_next->crd_flags &
  8374. + CRD_F_ENCRYPT) {
  8375. + sessionData->lacSessCtx.cipherSetupData.
  8376. + cipherDirection =
  8377. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  8378. + } else {
  8379. + sessionData->lacSessCtx.cipherSetupData.
  8380. + cipherDirection =
  8381. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  8382. + }
  8383. +
  8384. + }
  8385. +
  8386. + } else if (ICP_OCF_DRV_ALG_CIPHER ==
  8387. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  8388. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  8389. + sessionData->lacSessCtx.cipherSetupData.
  8390. + cipherDirection =
  8391. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  8392. + } else {
  8393. + sessionData->lacSessCtx.cipherSetupData.
  8394. + cipherDirection =
  8395. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  8396. + }
  8397. +
  8398. + }
  8399. +
  8400. + /*No action required for standalone Auth here */
  8401. +
  8402. + /* Allocate memory for SymSessionCtx before the Session Registration */
  8403. + lacStatus =
  8404. + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  8405. + &(sessionData->lacSessCtx),
  8406. + &sessionCtxSizeInBytes);
  8407. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8408. + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  8409. + __FUNCTION__, lacStatus);
  8410. + return EINVAL;
  8411. + }
  8412. + sessionData->sessHandle =
  8413. + kmalloc(sessionCtxSizeInBytes, GFP_ATOMIC);
  8414. + if (NULL == sessionData->sessHandle) {
  8415. + EPRINTK
  8416. + ("%s(): Failed to get memory for SymSessionCtx\n",
  8417. + __FUNCTION__);
  8418. + return ENOMEM;
  8419. + }
  8420. +
  8421. + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  8422. + icp_ocfDrvSymCallBack,
  8423. + &(sessionData->lacSessCtx),
  8424. + sessionData->sessHandle);
  8425. +
  8426. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8427. + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  8428. + __FUNCTION__, lacStatus);
  8429. + return EFAULT;
  8430. + }
  8431. +
  8432. + sessionData->inUse = ICP_SESSION_RUNNING;
  8433. + }
  8434. +
  8435. + drvOpData = kmem_cache_zalloc(drvOpData_zone, GFP_ATOMIC);
  8436. + if (NULL == drvOpData) {
  8437. + EPRINTK("%s():Failed to get memory for drvOpData\n",
  8438. + __FUNCTION__);
  8439. + crp->crp_etype = ENOMEM;
  8440. + return ENOMEM;
  8441. + }
  8442. +
  8443. + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  8444. + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  8445. + digestResultLenInBytes;
  8446. + drvOpData->crp = crp;
  8447. +
  8448. + /* Set the default buffer list array memory allocation */
  8449. + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  8450. + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  8451. +
  8452. + /*
  8453. + * Allocate buffer list array memory allocation if the
  8454. + * data fragment is more than the default allocation
  8455. + */
  8456. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  8457. + numBufferListArray = icp_ocfDrvGetSkBuffFrags((struct sk_buff *)
  8458. + crp->crp_buf);
  8459. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < numBufferListArray) {
  8460. + DPRINTK("%s() numBufferListArray more than default\n",
  8461. + __FUNCTION__);
  8462. + drvOpData->srcBuffer.pBuffers = NULL;
  8463. + drvOpData->srcBuffer.pBuffers =
  8464. + kmalloc(numBufferListArray *
  8465. + sizeof(CpaFlatBuffer), GFP_ATOMIC);
  8466. + if (NULL == drvOpData->srcBuffer.pBuffers) {
  8467. + EPRINTK("%s() Failed to get memory for "
  8468. + "pBuffers\n", __FUNCTION__);
  8469. + kmem_cache_free(drvOpData_zone, drvOpData);
  8470. + crp->crp_etype = ENOMEM;
  8471. + return ENOMEM;
  8472. + }
  8473. + drvOpData->numBufferListArray = numBufferListArray;
  8474. + }
  8475. + }
  8476. +
  8477. + /*
  8478. + * Check the type of buffer structure we got and convert it into
  8479. + * CpaBufferList format.
  8480. + */
  8481. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  8482. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  8483. + icp_ocfDrvSkBuffToBufferList((struct sk_buff *)crp->crp_buf,
  8484. + &(drvOpData->srcBuffer))) {
  8485. + EPRINTK("%s():Failed to translate from SK_BUF "
  8486. + "to bufferlist\n", __FUNCTION__);
  8487. + crp->crp_etype = EINVAL;
  8488. + goto err;
  8489. + }
  8490. +
  8491. + drvOpData->bufferType = CRYPTO_F_SKBUF;
  8492. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  8493. + /* OCF only supports IOV of one entry. */
  8494. + if (NUM_IOV_SUPPORTED ==
  8495. + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  8496. +
  8497. + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  8498. + crp_buf))->
  8499. + uio_iov[0].iov_base,
  8500. + ((struct uio *)(crp->
  8501. + crp_buf))->
  8502. + uio_iov[0].iov_len,
  8503. + &(drvOpData->
  8504. + srcBuffer));
  8505. +
  8506. + drvOpData->bufferType = CRYPTO_F_IOV;
  8507. +
  8508. + } else {
  8509. + DPRINTK("%s():Unable to handle IOVs with lengths of "
  8510. + "greater than one!\n", __FUNCTION__);
  8511. + crp->crp_etype = EINVAL;
  8512. + goto err;
  8513. + }
  8514. +
  8515. + } else {
  8516. + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  8517. + crp->crp_ilen,
  8518. + &(drvOpData->srcBuffer));
  8519. +
  8520. + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  8521. + }
  8522. +
  8523. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  8524. + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  8525. + crp->crp_etype = EINVAL;
  8526. + goto err;
  8527. + }
  8528. +
  8529. + if (drvOpData->crp->crp_desc->crd_next != NULL) {
  8530. + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  8531. + crp_desc->crd_next)) {
  8532. + crp->crp_etype = EINVAL;
  8533. + goto err;
  8534. + }
  8535. +
  8536. + }
  8537. +
  8538. + /* Allocate srcBuffer's private meta data */
  8539. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  8540. + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  8541. + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  8542. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  8543. + crp->crp_etype = EINVAL;
  8544. + goto err;
  8545. + }
  8546. +
  8547. + /* Perform "in-place" crypto operation */
  8548. + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  8549. + (void *)drvOpData,
  8550. + &(drvOpData->lacOpData),
  8551. + &(drvOpData->srcBuffer),
  8552. + &(drvOpData->srcBuffer),
  8553. + &(drvOpData->verifyResult));
  8554. + if (CPA_STATUS_RETRY == lacStatus) {
  8555. + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  8556. + __FUNCTION__, lacStatus);
  8557. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  8558. + crp->crp_etype = EINVAL;
  8559. + goto err;
  8560. + }
  8561. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8562. + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  8563. + __FUNCTION__, lacStatus);
  8564. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  8565. + crp->crp_etype = EINVAL;
  8566. + goto err;
  8567. + }
  8568. +
  8569. + return 0; //OCF success status value
  8570. +
  8571. + err:
  8572. + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  8573. + kfree(drvOpData->srcBuffer.pBuffers);
  8574. + }
  8575. + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  8576. + kmem_cache_free(drvOpData_zone, drvOpData);
  8577. +
  8578. + return crp->crp_etype;
  8579. +}
  8580. +
  8581. +/* Name : icp_ocfDrvProcessDataSetup
  8582. + *
  8583. + * Description : This function will setup all the cryptographic operation data
  8584. + * that is required by LAC to execute the operation.
  8585. + */
  8586. +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  8587. + struct cryptodesc *crp_desc)
  8588. +{
  8589. + CpaCyRandGenOpData randGenOpData;
  8590. + CpaFlatBuffer randData;
  8591. +
  8592. + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  8593. +
  8594. + /* Convert from the cryptop to the ICP LAC crypto parameters */
  8595. + switch (crp_desc->crd_alg) {
  8596. + case CRYPTO_NULL_CBC:
  8597. + drvOpData->lacOpData.
  8598. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8599. + drvOpData->lacOpData.
  8600. + messageLenToCipherInBytes = crp_desc->crd_len;
  8601. + drvOpData->verifyResult = CPA_FALSE;
  8602. + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  8603. + break;
  8604. + case CRYPTO_DES_CBC:
  8605. + drvOpData->lacOpData.
  8606. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8607. + drvOpData->lacOpData.
  8608. + messageLenToCipherInBytes = crp_desc->crd_len;
  8609. + drvOpData->verifyResult = CPA_FALSE;
  8610. + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  8611. + break;
  8612. + case CRYPTO_3DES_CBC:
  8613. + drvOpData->lacOpData.
  8614. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8615. + drvOpData->lacOpData.
  8616. + messageLenToCipherInBytes = crp_desc->crd_len;
  8617. + drvOpData->verifyResult = CPA_FALSE;
  8618. + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  8619. + break;
  8620. + case CRYPTO_ARC4:
  8621. + drvOpData->lacOpData.
  8622. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8623. + drvOpData->lacOpData.
  8624. + messageLenToCipherInBytes = crp_desc->crd_len;
  8625. + drvOpData->verifyResult = CPA_FALSE;
  8626. + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  8627. + break;
  8628. + case CRYPTO_AES_CBC:
  8629. + drvOpData->lacOpData.
  8630. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  8631. + drvOpData->lacOpData.
  8632. + messageLenToCipherInBytes = crp_desc->crd_len;
  8633. + drvOpData->verifyResult = CPA_FALSE;
  8634. + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  8635. + break;
  8636. + case CRYPTO_SHA1:
  8637. + case CRYPTO_SHA1_HMAC:
  8638. + case CRYPTO_SHA2_256:
  8639. + case CRYPTO_SHA2_256_HMAC:
  8640. + case CRYPTO_SHA2_384:
  8641. + case CRYPTO_SHA2_384_HMAC:
  8642. + case CRYPTO_SHA2_512:
  8643. + case CRYPTO_SHA2_512_HMAC:
  8644. + case CRYPTO_MD5:
  8645. + case CRYPTO_MD5_HMAC:
  8646. + drvOpData->lacOpData.
  8647. + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  8648. + drvOpData->lacOpData.
  8649. + messageLenToHashInBytes = crp_desc->crd_len;
  8650. + drvOpData->lacOpData.
  8651. + pDigestResult =
  8652. + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  8653. +
  8654. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  8655. + DPRINTK("%s(): ERROR - could not calculate "
  8656. + "Digest Result memory address\n", __FUNCTION__);
  8657. + return ICP_OCF_DRV_STATUS_FAIL;
  8658. + }
  8659. +
  8660. + drvOpData->lacOpData.digestVerify = CPA_FALSE;
  8661. + break;
  8662. + default:
  8663. + DPRINTK("%s(): Crypto process error - algorithm not "
  8664. + "found \n", __FUNCTION__);
  8665. + return ICP_OCF_DRV_STATUS_FAIL;
  8666. + }
  8667. +
  8668. + /* Figure out what the IV is supposed to be */
  8669. + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  8670. + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  8671. + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  8672. + /*ARC4 doesn't use an IV */
  8673. + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  8674. + /* Explicit IV provided to OCF */
  8675. + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  8676. + } else {
  8677. + /* IV is not explicitly provided to OCF */
  8678. +
  8679. + /* Point the LAC OP Data IV pointer to our allocated
  8680. + storage location for this session. */
  8681. + drvOpData->lacOpData.pIv = drvOpData->ivData;
  8682. +
  8683. + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  8684. + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  8685. +
  8686. + /* Encrypting - need to create IV */
  8687. + randGenOpData.generateBits = CPA_TRUE;
  8688. + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  8689. +
  8690. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  8691. + drvOpData->
  8692. + ivData,
  8693. + MAX_IV_LEN_IN_BYTES,
  8694. + &randData);
  8695. +
  8696. + if (CPA_STATUS_SUCCESS !=
  8697. + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  8698. + NULL, NULL,
  8699. + &randGenOpData, &randData)) {
  8700. + DPRINTK("%s(): ERROR - Failed to"
  8701. + " generate"
  8702. + " Initialisation Vector\n",
  8703. + __FUNCTION__);
  8704. + return ICP_OCF_DRV_STATUS_FAIL;
  8705. + }
  8706. +
  8707. + crypto_copyback(drvOpData->crp->
  8708. + crp_flags,
  8709. + drvOpData->crp->crp_buf,
  8710. + crp_desc->crd_inject,
  8711. + drvOpData->lacOpData.
  8712. + ivLenInBytes,
  8713. + (caddr_t) (drvOpData->lacOpData.
  8714. + pIv));
  8715. + } else {
  8716. + /* Reading IV from buffer */
  8717. + crypto_copydata(drvOpData->crp->
  8718. + crp_flags,
  8719. + drvOpData->crp->crp_buf,
  8720. + crp_desc->crd_inject,
  8721. + drvOpData->lacOpData.
  8722. + ivLenInBytes,
  8723. + (caddr_t) (drvOpData->lacOpData.
  8724. + pIv));
  8725. + }
  8726. +
  8727. + }
  8728. +
  8729. + }
  8730. +
  8731. + return ICP_OCF_DRV_STATUS_SUCCESS;
  8732. +}
  8733. +
  8734. +/* Name : icp_ocfDrvDigestPointerFind
  8735. + *
  8736. + * Description : This function is used to find the memory address of where the
  8737. + * digest information shall be stored in. Input buffer types are an skbuff, iov
  8738. + * or flat buffer. The address is found using the buffer data start address and
  8739. + * an offset.
  8740. + *
  8741. + * Note: In the case of a linux skbuff, the digest address may exist within
  8742. + * a memory space linked to from the start buffer. These linked memory spaces
  8743. + * must be traversed by the data length offset in order to find the digest start
  8744. + * address. Whether there is enough space for the digest must also be checked.
  8745. + */
  8746. +
  8747. +static uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  8748. + struct cryptodesc *crp_desc)
  8749. +{
  8750. +
  8751. + int offsetInBytes = crp_desc->crd_inject;
  8752. + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  8753. + uint8_t *flat_buffer_base = NULL;
  8754. + int flat_buffer_length = 0;
  8755. + struct sk_buff *skb;
  8756. +
  8757. + if (drvOpData->crp->crp_flags & CRYPTO_F_SKBUF) {
  8758. + /*check if enough overall space to store hash */
  8759. + skb = (struct sk_buff *)(drvOpData->crp->crp_buf);
  8760. +
  8761. + if (skb->len < (offsetInBytes + digestSizeInBytes)) {
  8762. + DPRINTK("%s() Not enough space for Digest"
  8763. + " payload after the offset (%d), "
  8764. + "digest size (%d) \n", __FUNCTION__,
  8765. + offsetInBytes, digestSizeInBytes);
  8766. + return NULL;
  8767. + }
  8768. +
  8769. + return icp_ocfDrvSkbuffDigestPointerFind(drvOpData,
  8770. + offsetInBytes,
  8771. + digestSizeInBytes);
  8772. +
  8773. + } else {
  8774. + /* IOV or flat buffer */
  8775. + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  8776. + /*single IOV check has already been done */
  8777. + flat_buffer_base = ((struct uio *)
  8778. + (drvOpData->crp->crp_buf))->
  8779. + uio_iov[0].iov_base;
  8780. + flat_buffer_length = ((struct uio *)
  8781. + (drvOpData->crp->crp_buf))->
  8782. + uio_iov[0].iov_len;
  8783. + } else {
  8784. + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  8785. + flat_buffer_length = drvOpData->crp->crp_ilen;
  8786. + }
  8787. +
  8788. + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  8789. + DPRINTK("%s() Not enough space for Digest "
  8790. + "(IOV/Flat Buffer) \n", __FUNCTION__);
  8791. + return NULL;
  8792. + } else {
  8793. + return (uint8_t *) (flat_buffer_base + offsetInBytes);
  8794. + }
  8795. + }
  8796. + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  8797. + return NULL;
  8798. +}
  8799. +
  8800. +/* Name : icp_ocfDrvSkbuffDigestPointerFind
  8801. + *
  8802. + * Description : This function is used by icp_ocfDrvDigestPointerFind to process
  8803. + * the non-linear portion of the skbuff if the fragmentation type is a linked
  8804. + * list (frag_list is not NULL in the skb_shared_info structure)
  8805. + */
  8806. +static inline uint8_t *icp_ocfDrvSkbuffDigestPointerFind(struct icp_drvOpData
  8807. + *drvOpData,
  8808. + int offsetInBytes,
  8809. + uint32_t
  8810. + digestSizeInBytes)
  8811. +{
  8812. +
  8813. + struct sk_buff *skb = NULL;
  8814. + struct skb_shared_info *skb_shared = NULL;
  8815. +
  8816. + uint32_t skbuffisnonlinear = 0;
  8817. +
  8818. + uint32_t skbheadlen = 0;
  8819. +
  8820. + skb = (struct sk_buff *)(drvOpData->crp->crp_buf);
  8821. + skbuffisnonlinear = skb_is_nonlinear(skb);
  8822. +
  8823. + skbheadlen = skb_headlen(skb);
  8824. +
  8825. + /*Linear skb checks */
  8826. + if (skbheadlen > offsetInBytes) {
  8827. +
  8828. + if (skbheadlen >= (offsetInBytes + digestSizeInBytes)) {
  8829. + return (uint8_t *) (skb->data + offsetInBytes);
  8830. + } else {
  8831. + DPRINTK("%s() Auth payload stretches "
  8832. + "accross contiguous memory\n", __FUNCTION__);
  8833. + return NULL;
  8834. + }
  8835. + } else {
  8836. + if (skbuffisnonlinear) {
  8837. + offsetInBytes -= skbheadlen;
  8838. + } else {
  8839. + DPRINTK("%s() Offset outside of buffer boundaries\n",
  8840. + __FUNCTION__);
  8841. + return NULL;
  8842. + }
  8843. + }
  8844. +
  8845. + /*Non Linear checks */
  8846. + skb_shared = (struct skb_shared_info *)(skb->end);
  8847. + if (unlikely(NULL == skb_shared)) {
  8848. + DPRINTK("%s() skbuff shared info stucture is NULL! \n",
  8849. + __FUNCTION__);
  8850. + return NULL;
  8851. + } else if ((0 != skb_shared->nr_frags) &&
  8852. + (skb_shared->frag_list != NULL)) {
  8853. + DPRINTK("%s() skbuff nr_frags AND "
  8854. + "frag_list not supported \n", __FUNCTION__);
  8855. + return NULL;
  8856. + }
  8857. +
  8858. + /*TCP segmentation more likely than IP fragmentation */
  8859. + if (likely(0 != skb_shared->nr_frags)) {
  8860. + return icp_ocfDrvDigestSkbNRFragsCheck(skb, skb_shared,
  8861. + offsetInBytes,
  8862. + digestSizeInBytes);
  8863. + } else if (skb_shared->frag_list != NULL) {
  8864. + return icp_ocfDrvDigestSkbFragListCheck(skb, skb_shared,
  8865. + offsetInBytes,
  8866. + digestSizeInBytes);
  8867. + } else {
  8868. + DPRINTK("%s() skbuff is non-linear but does not show any "
  8869. + "linked data\n", __FUNCTION__);
  8870. + return NULL;
  8871. + }
  8872. +
  8873. +}
  8874. +
  8875. +/* Name : icp_ocfDrvDigestSkbNRFragsCheck
  8876. + *
  8877. + * Description : This function is used by icp_ocfDrvSkbuffDigestPointerFind to
  8878. + * process the non-linear portion of the skbuff, if the fragmentation type is
  8879. + * page fragments
  8880. + */
  8881. +static inline uint8_t *icp_ocfDrvDigestSkbNRFragsCheck(struct sk_buff *skb,
  8882. + struct skb_shared_info
  8883. + *skb_shared,
  8884. + int offsetInBytes,
  8885. + uint32_t
  8886. + digestSizeInBytes)
  8887. +{
  8888. + int i = 0;
  8889. + /*nr_frags starts from 1 */
  8890. + if (MAX_SKB_FRAGS < skb_shared->nr_frags) {
  8891. + DPRINTK("%s error processing skbuff "
  8892. + "page frame -- MAX FRAGS exceeded \n", __FUNCTION__);
  8893. + return NULL;
  8894. + }
  8895. +
  8896. + for (i = 0; i < skb_shared->nr_frags; i++) {
  8897. +
  8898. + if (offsetInBytes >= skb_shared->frags[i].size) {
  8899. + /*offset still greater than data position */
  8900. + offsetInBytes -= skb_shared->frags[i].size;
  8901. + } else {
  8902. + /* found the page containing start of hash */
  8903. +
  8904. + if (NULL == skb_shared->frags[i].page) {
  8905. + DPRINTK("%s() Linked page is NULL!\n",
  8906. + __FUNCTION__);
  8907. + return NULL;
  8908. + }
  8909. +
  8910. + if (offsetInBytes + digestSizeInBytes >
  8911. + skb_shared->frags[i].size) {
  8912. + DPRINTK("%s() Auth payload stretches accross "
  8913. + "contiguous memory\n", __FUNCTION__);
  8914. + return NULL;
  8915. + } else {
  8916. + return (uint8_t *) (skb_shared->frags[i].page +
  8917. + skb_shared->frags[i].
  8918. + page_offset +
  8919. + offsetInBytes);
  8920. + }
  8921. + }
  8922. + /*only possible if internal page sizes are set wrong */
  8923. + if (offsetInBytes < 0) {
  8924. + DPRINTK("%s error processing skbuff page frame "
  8925. + "-- offset calculation \n", __FUNCTION__);
  8926. + return NULL;
  8927. + }
  8928. + }
  8929. + /*only possible if internal page sizes are set wrong */
  8930. + DPRINTK("%s error processing skbuff page frame "
  8931. + "-- ran out of page fragments, remaining offset = %d \n",
  8932. + __FUNCTION__, offsetInBytes);
  8933. + return NULL;
  8934. +
  8935. +}
  8936. +
  8937. +/* Name : icp_ocfDrvDigestSkbFragListCheck
  8938. + *
  8939. + * Description : This function is used by icp_ocfDrvSkbuffDigestPointerFind to
  8940. + * process the non-linear portion of the skbuff, if the fragmentation type is
  8941. + * a linked list
  8942. + *
  8943. + */
  8944. +static inline uint8_t *icp_ocfDrvDigestSkbFragListCheck(struct sk_buff *skb,
  8945. + struct skb_shared_info
  8946. + *skb_shared,
  8947. + int offsetInBytes,
  8948. + uint32_t
  8949. + digestSizeInBytes)
  8950. +{
  8951. +
  8952. + struct sk_buff *skb_list = skb_shared->frag_list;
  8953. + /*check added for readability */
  8954. + if (NULL == skb_list) {
  8955. + DPRINTK("%s error processing skbuff "
  8956. + "-- no more list! \n", __FUNCTION__);
  8957. + return NULL;
  8958. + }
  8959. +
  8960. + for (; skb_list; skb_list = skb_list->next) {
  8961. + if (NULL == skb_list) {
  8962. + DPRINTK("%s error processing skbuff "
  8963. + "-- no more list! \n", __FUNCTION__);
  8964. + return NULL;
  8965. + }
  8966. +
  8967. + if (offsetInBytes >= skb_list->len) {
  8968. + offsetInBytes -= skb_list->len;
  8969. +
  8970. + } else {
  8971. + if (offsetInBytes + digestSizeInBytes > skb_list->len) {
  8972. + DPRINTK("%s() Auth payload stretches accross "
  8973. + "contiguous memory\n", __FUNCTION__);
  8974. + return NULL;
  8975. + } else {
  8976. + return (uint8_t *)
  8977. + (skb_list->data + offsetInBytes);
  8978. + }
  8979. +
  8980. + }
  8981. +
  8982. + /*This check is only needed if internal skb_list length values
  8983. + are set wrong. */
  8984. + if (0 > offsetInBytes) {
  8985. + DPRINTK("%s() error processing skbuff object -- offset "
  8986. + "calculation \n", __FUNCTION__);
  8987. + return NULL;
  8988. + }
  8989. +
  8990. + }
  8991. +
  8992. + /*catch all for unusual for-loop exit.
  8993. + This code should never be reached */
  8994. + DPRINTK("%s() Catch-All hit! Process error.\n", __FUNCTION__);
  8995. + return NULL;
  8996. +}
  8997. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/Makefile linux-2.6.29.1/crypto/ocf/hifn/Makefile
  8998. --- linux-2.6.29.1.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
  8999. +++ linux-2.6.29.1/crypto/ocf/hifn/Makefile 2009-04-20 20:01:21.516556358 +0200
  9000. @@ -0,0 +1,13 @@
  9001. +# for SGlinux builds
  9002. +-include $(ROOTDIR)/modules/.config
  9003. +
  9004. +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
  9005. +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
  9006. +
  9007. +obj ?= .
  9008. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  9009. +
  9010. +ifdef TOPDIR
  9011. +-include $(TOPDIR)/Rules.make
  9012. +endif
  9013. +
  9014. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.29.1/crypto/ocf/hifn/hifn7751.c
  9015. --- linux-2.6.29.1.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
  9016. +++ linux-2.6.29.1/crypto/ocf/hifn/hifn7751.c 2009-04-20 20:01:21.484554239 +0200
  9017. @@ -0,0 +1,2970 @@
  9018. +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
  9019. +
  9020. +/*-
  9021. + * Invertex AEON / Hifn 7751 driver
  9022. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  9023. + * Copyright (c) 1999 Theo de Raadt
  9024. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  9025. + * http://www.netsec.net
  9026. + * Copyright (c) 2003 Hifn Inc.
  9027. + *
  9028. + * This driver is based on a previous driver by Invertex, for which they
  9029. + * requested: Please send any comments, feedback, bug-fixes, or feature
  9030. + * requests to software@invertex.com.
  9031. + *
  9032. + * Redistribution and use in source and binary forms, with or without
  9033. + * modification, are permitted provided that the following conditions
  9034. + * are met:
  9035. + *
  9036. + * 1. Redistributions of source code must retain the above copyright
  9037. + * notice, this list of conditions and the following disclaimer.
  9038. + * 2. Redistributions in binary form must reproduce the above copyright
  9039. + * notice, this list of conditions and the following disclaimer in the
  9040. + * documentation and/or other materials provided with the distribution.
  9041. + * 3. The name of the author may not be used to endorse or promote products
  9042. + * derived from this software without specific prior written permission.
  9043. + *
  9044. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  9045. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  9046. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  9047. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  9048. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  9049. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  9050. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  9051. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  9052. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  9053. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  9054. + *
  9055. + * Effort sponsored in part by the Defense Advanced Research Projects
  9056. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  9057. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  9058. + *
  9059. + *
  9060. +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
  9061. + */
  9062. +
  9063. +/*
  9064. + * Driver for various Hifn encryption processors.
  9065. + */
  9066. +#ifndef AUTOCONF_INCLUDED
  9067. +#include <linux/config.h>
  9068. +#endif
  9069. +#include <linux/module.h>
  9070. +#include <linux/init.h>
  9071. +#include <linux/list.h>
  9072. +#include <linux/slab.h>
  9073. +#include <linux/wait.h>
  9074. +#include <linux/sched.h>
  9075. +#include <linux/pci.h>
  9076. +#include <linux/delay.h>
  9077. +#include <linux/interrupt.h>
  9078. +#include <linux/spinlock.h>
  9079. +#include <linux/random.h>
  9080. +#include <linux/version.h>
  9081. +#include <linux/skbuff.h>
  9082. +#include <asm/io.h>
  9083. +
  9084. +#include <cryptodev.h>
  9085. +#include <uio.h>
  9086. +#include <hifn/hifn7751reg.h>
  9087. +#include <hifn/hifn7751var.h>
  9088. +
  9089. +#if 1
  9090. +#define DPRINTF(a...) if (hifn_debug) { \
  9091. + printk("%s: ", sc ? \
  9092. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  9093. + printk(a); \
  9094. + } else
  9095. +#else
  9096. +#define DPRINTF(a...)
  9097. +#endif
  9098. +
  9099. +static inline int
  9100. +pci_get_revid(struct pci_dev *dev)
  9101. +{
  9102. + u8 rid = 0;
  9103. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  9104. + return rid;
  9105. +}
  9106. +
  9107. +static struct hifn_stats hifnstats;
  9108. +
  9109. +#define debug hifn_debug
  9110. +int hifn_debug = 0;
  9111. +module_param(hifn_debug, int, 0644);
  9112. +MODULE_PARM_DESC(hifn_debug, "Enable debug");
  9113. +
  9114. +int hifn_maxbatch = 1;
  9115. +module_param(hifn_maxbatch, int, 0644);
  9116. +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
  9117. +
  9118. +#ifdef MODULE_PARM
  9119. +char *hifn_pllconfig = NULL;
  9120. +MODULE_PARM(hifn_pllconfig, "s");
  9121. +#else
  9122. +char hifn_pllconfig[32]; /* This setting is RO after loading */
  9123. +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
  9124. +#endif
  9125. +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
  9126. +
  9127. +#ifdef HIFN_VULCANDEV
  9128. +#include <sys/conf.h>
  9129. +#include <sys/uio.h>
  9130. +
  9131. +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
  9132. +#endif
  9133. +
  9134. +/*
  9135. + * Prototypes and count for the pci_device structure
  9136. + */
  9137. +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  9138. +static void hifn_remove(struct pci_dev *dev);
  9139. +
  9140. +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
  9141. +static int hifn_freesession(device_t, u_int64_t);
  9142. +static int hifn_process(device_t, struct cryptop *, int);
  9143. +
  9144. +static device_method_t hifn_methods = {
  9145. + /* crypto device methods */
  9146. + DEVMETHOD(cryptodev_newsession, hifn_newsession),
  9147. + DEVMETHOD(cryptodev_freesession,hifn_freesession),
  9148. + DEVMETHOD(cryptodev_process, hifn_process),
  9149. +};
  9150. +
  9151. +static void hifn_reset_board(struct hifn_softc *, int);
  9152. +static void hifn_reset_puc(struct hifn_softc *);
  9153. +static void hifn_puc_wait(struct hifn_softc *);
  9154. +static int hifn_enable_crypto(struct hifn_softc *);
  9155. +static void hifn_set_retry(struct hifn_softc *sc);
  9156. +static void hifn_init_dma(struct hifn_softc *);
  9157. +static void hifn_init_pci_registers(struct hifn_softc *);
  9158. +static int hifn_sramsize(struct hifn_softc *);
  9159. +static int hifn_dramsize(struct hifn_softc *);
  9160. +static int hifn_ramtype(struct hifn_softc *);
  9161. +static void hifn_sessions(struct hifn_softc *);
  9162. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  9163. +static irqreturn_t hifn_intr(int irq, void *arg);
  9164. +#else
  9165. +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
  9166. +#endif
  9167. +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
  9168. +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
  9169. +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
  9170. +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
  9171. +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
  9172. +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
  9173. +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
  9174. +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
  9175. +static int hifn_init_pubrng(struct hifn_softc *);
  9176. +static void hifn_tick(unsigned long arg);
  9177. +static void hifn_abort(struct hifn_softc *);
  9178. +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
  9179. +
  9180. +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
  9181. +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
  9182. +
  9183. +#ifdef CONFIG_OCF_RANDOMHARVEST
  9184. +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
  9185. +#endif
  9186. +
  9187. +#define HIFN_MAX_CHIPS 8
  9188. +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
  9189. +
  9190. +static __inline u_int32_t
  9191. +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
  9192. +{
  9193. + u_int32_t v = readl(sc->sc_bar0 + reg);
  9194. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  9195. + return (v);
  9196. +}
  9197. +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
  9198. +
  9199. +static __inline u_int32_t
  9200. +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
  9201. +{
  9202. + u_int32_t v = readl(sc->sc_bar1 + reg);
  9203. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  9204. + return (v);
  9205. +}
  9206. +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
  9207. +
  9208. +/*
  9209. + * map in a given buffer (great on some arches :-)
  9210. + */
  9211. +
  9212. +static int
  9213. +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
  9214. +{
  9215. + struct iovec *iov = uio->uio_iov;
  9216. +
  9217. + DPRINTF("%s()\n", __FUNCTION__);
  9218. +
  9219. + buf->mapsize = 0;
  9220. + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
  9221. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  9222. + iov->iov_base, iov->iov_len,
  9223. + PCI_DMA_BIDIRECTIONAL);
  9224. + buf->segs[buf->nsegs].ds_len = iov->iov_len;
  9225. + buf->mapsize += iov->iov_len;
  9226. + iov++;
  9227. + buf->nsegs++;
  9228. + }
  9229. + /* identify this buffer by the first segment */
  9230. + buf->map = (void *) buf->segs[0].ds_addr;
  9231. + return(0);
  9232. +}
  9233. +
  9234. +/*
  9235. + * map in a given sk_buff
  9236. + */
  9237. +
  9238. +static int
  9239. +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
  9240. +{
  9241. + int i;
  9242. +
  9243. + DPRINTF("%s()\n", __FUNCTION__);
  9244. +
  9245. + buf->mapsize = 0;
  9246. +
  9247. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  9248. + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
  9249. + buf->segs[0].ds_len = skb_headlen(skb);
  9250. + buf->mapsize += buf->segs[0].ds_len;
  9251. +
  9252. + buf->nsegs = 1;
  9253. +
  9254. + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
  9255. + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
  9256. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  9257. + page_address(skb_shinfo(skb)->frags[i].page) +
  9258. + skb_shinfo(skb)->frags[i].page_offset,
  9259. + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
  9260. + buf->mapsize += buf->segs[buf->nsegs].ds_len;
  9261. + buf->nsegs++;
  9262. + }
  9263. +
  9264. + /* identify this buffer by the first segment */
  9265. + buf->map = (void *) buf->segs[0].ds_addr;
  9266. + return(0);
  9267. +}
  9268. +
  9269. +/*
  9270. + * map in a given contiguous buffer
  9271. + */
  9272. +
  9273. +static int
  9274. +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
  9275. +{
  9276. + DPRINTF("%s()\n", __FUNCTION__);
  9277. +
  9278. + buf->mapsize = 0;
  9279. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  9280. + b, len, PCI_DMA_BIDIRECTIONAL);
  9281. + buf->segs[0].ds_len = len;
  9282. + buf->mapsize += buf->segs[0].ds_len;
  9283. + buf->nsegs = 1;
  9284. +
  9285. + /* identify this buffer by the first segment */
  9286. + buf->map = (void *) buf->segs[0].ds_addr;
  9287. + return(0);
  9288. +}
  9289. +
  9290. +#if 0 /* not needed at this time */
  9291. +static void
  9292. +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
  9293. +{
  9294. + int i;
  9295. +
  9296. + DPRINTF("%s()\n", __FUNCTION__);
  9297. + for (i = 0; i < buf->nsegs; i++)
  9298. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  9299. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  9300. +}
  9301. +#endif
  9302. +
  9303. +static void
  9304. +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
  9305. +{
  9306. + int i;
  9307. + DPRINTF("%s()\n", __FUNCTION__);
  9308. + for (i = 0; i < buf->nsegs; i++) {
  9309. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  9310. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  9311. + buf->segs[i].ds_addr = 0;
  9312. + buf->segs[i].ds_len = 0;
  9313. + }
  9314. + buf->nsegs = 0;
  9315. + buf->mapsize = 0;
  9316. + buf->map = 0;
  9317. +}
  9318. +
  9319. +static const char*
  9320. +hifn_partname(struct hifn_softc *sc)
  9321. +{
  9322. + /* XXX sprintf numbers when not decoded */
  9323. + switch (pci_get_vendor(sc->sc_pcidev)) {
  9324. + case PCI_VENDOR_HIFN:
  9325. + switch (pci_get_device(sc->sc_pcidev)) {
  9326. + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
  9327. + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
  9328. + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
  9329. + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
  9330. + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
  9331. + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
  9332. + }
  9333. + return "Hifn unknown-part";
  9334. + case PCI_VENDOR_INVERTEX:
  9335. + switch (pci_get_device(sc->sc_pcidev)) {
  9336. + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
  9337. + }
  9338. + return "Invertex unknown-part";
  9339. + case PCI_VENDOR_NETSEC:
  9340. + switch (pci_get_device(sc->sc_pcidev)) {
  9341. + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
  9342. + }
  9343. + return "NetSec unknown-part";
  9344. + }
  9345. + return "Unknown-vendor unknown-part";
  9346. +}
  9347. +
  9348. +static u_int
  9349. +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
  9350. +{
  9351. + struct hifn_softc *sc = pci_get_drvdata(dev);
  9352. + if (v > max) {
  9353. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  9354. + "using max %u\n", what, v, max);
  9355. + v = max;
  9356. + } else if (v < min) {
  9357. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  9358. + "using min %u\n", what, v, min);
  9359. + v = min;
  9360. + }
  9361. + return v;
  9362. +}
  9363. +
  9364. +/*
  9365. + * Select PLL configuration for 795x parts. This is complicated in
  9366. + * that we cannot determine the optimal parameters without user input.
  9367. + * The reference clock is derived from an external clock through a
  9368. + * multiplier. The external clock is either the host bus (i.e. PCI)
  9369. + * or an external clock generator. When using the PCI bus we assume
  9370. + * the clock is either 33 or 66 MHz; for an external source we cannot
  9371. + * tell the speed.
  9372. + *
  9373. + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
  9374. + * for an external source, followed by the frequency. We calculate
  9375. + * the appropriate multiplier and PLL register contents accordingly.
  9376. + * When no configuration is given we default to "pci66" since that
  9377. + * always will allow the card to work. If a card is using the PCI
  9378. + * bus clock and in a 33MHz slot then it will be operating at half
  9379. + * speed until the correct information is provided.
  9380. + *
  9381. + * We use a default setting of "ext66" because according to Mike Ham
  9382. + * of HiFn, almost every board in existence has an external crystal
  9383. + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
  9384. + * because PCI33 can have clocks from 0 to 33Mhz, and some have
  9385. + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
  9386. + */
  9387. +static void
  9388. +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
  9389. +{
  9390. + const char *pllspec = hifn_pllconfig;
  9391. + u_int freq, mul, fl, fh;
  9392. + u_int32_t pllconfig;
  9393. + char *nxt;
  9394. +
  9395. + if (pllspec == NULL)
  9396. + pllspec = "ext66";
  9397. + fl = 33, fh = 66;
  9398. + pllconfig = 0;
  9399. + if (strncmp(pllspec, "ext", 3) == 0) {
  9400. + pllspec += 3;
  9401. + pllconfig |= HIFN_PLL_REF_SEL;
  9402. + switch (pci_get_device(dev)) {
  9403. + case PCI_PRODUCT_HIFN_7955:
  9404. + case PCI_PRODUCT_HIFN_7956:
  9405. + fl = 20, fh = 100;
  9406. + break;
  9407. +#ifdef notyet
  9408. + case PCI_PRODUCT_HIFN_7954:
  9409. + fl = 20, fh = 66;
  9410. + break;
  9411. +#endif
  9412. + }
  9413. + } else if (strncmp(pllspec, "pci", 3) == 0)
  9414. + pllspec += 3;
  9415. + freq = strtoul(pllspec, &nxt, 10);
  9416. + if (nxt == pllspec)
  9417. + freq = 66;
  9418. + else
  9419. + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
  9420. + /*
  9421. + * Calculate multiplier. We target a Fck of 266 MHz,
  9422. + * allowing only even values, possibly rounded down.
  9423. + * Multipliers > 8 must set the charge pump current.
  9424. + */
  9425. + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
  9426. + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
  9427. + if (mul > 8)
  9428. + pllconfig |= HIFN_PLL_IS;
  9429. + *pll = pllconfig;
  9430. +}
  9431. +
  9432. +/*
  9433. + * Attach an interface that successfully probed.
  9434. + */
  9435. +static int
  9436. +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  9437. +{
  9438. + struct hifn_softc *sc = NULL;
  9439. + char rbase;
  9440. + u_int16_t ena, rev;
  9441. + int rseg, rc;
  9442. + unsigned long mem_start, mem_len;
  9443. + static int num_chips = 0;
  9444. +
  9445. + DPRINTF("%s()\n", __FUNCTION__);
  9446. +
  9447. + if (pci_enable_device(dev) < 0)
  9448. + return(-ENODEV);
  9449. +
  9450. + if (pci_set_mwi(dev))
  9451. + return(-ENODEV);
  9452. +
  9453. + if (!dev->irq) {
  9454. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  9455. + pci_disable_device(dev);
  9456. + return(-ENODEV);
  9457. + }
  9458. +
  9459. + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  9460. + if (!sc)
  9461. + return(-ENOMEM);
  9462. + memset(sc, 0, sizeof(*sc));
  9463. +
  9464. + softc_device_init(sc, "hifn", num_chips, hifn_methods);
  9465. +
  9466. + sc->sc_pcidev = dev;
  9467. + sc->sc_irq = -1;
  9468. + sc->sc_cid = -1;
  9469. + sc->sc_num = num_chips++;
  9470. + if (sc->sc_num < HIFN_MAX_CHIPS)
  9471. + hifn_chip_idx[sc->sc_num] = sc;
  9472. +
  9473. + pci_set_drvdata(sc->sc_pcidev, sc);
  9474. +
  9475. + spin_lock_init(&sc->sc_mtx);
  9476. +
  9477. + /* XXX handle power management */
  9478. +
  9479. + /*
  9480. + * The 7951 and 795x have a random number generator and
  9481. + * public key support; note this.
  9482. + */
  9483. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  9484. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
  9485. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  9486. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
  9487. + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
  9488. + /*
  9489. + * The 7811 has a random number generator and
  9490. + * we also note it's identity 'cuz of some quirks.
  9491. + */
  9492. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  9493. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
  9494. + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
  9495. +
  9496. + /*
  9497. + * The 795x parts support AES.
  9498. + */
  9499. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  9500. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  9501. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
  9502. + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
  9503. + /*
  9504. + * Select PLL configuration. This depends on the
  9505. + * bus and board design and must be manually configured
  9506. + * if the default setting is unacceptable.
  9507. + */
  9508. + hifn_getpllconfig(dev, &sc->sc_pllconfig);
  9509. + }
  9510. +
  9511. + /*
  9512. + * Setup PCI resources. Note that we record the bus
  9513. + * tag and handle for each register mapping, this is
  9514. + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
  9515. + * and WRITE_REG_1 macros throughout the driver.
  9516. + */
  9517. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  9518. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  9519. + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  9520. + if (!sc->sc_bar0) {
  9521. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
  9522. + goto fail;
  9523. + }
  9524. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  9525. +
  9526. + mem_start = pci_resource_start(sc->sc_pcidev, 1);
  9527. + mem_len = pci_resource_len(sc->sc_pcidev, 1);
  9528. + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  9529. + if (!sc->sc_bar1) {
  9530. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
  9531. + goto fail;
  9532. + }
  9533. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  9534. +
  9535. + /* fix up the bus size */
  9536. + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
  9537. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  9538. + goto fail;
  9539. + }
  9540. + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
  9541. + device_printf(sc->sc_dev,
  9542. + "No usable consistent DMA configuration, aborting.\n");
  9543. + goto fail;
  9544. + }
  9545. +
  9546. + hifn_set_retry(sc);
  9547. +
  9548. + /*
  9549. + * Setup the area where the Hifn DMA's descriptors
  9550. + * and associated data structures.
  9551. + */
  9552. + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
  9553. + sizeof(*sc->sc_dma),
  9554. + &sc->sc_dma_physaddr);
  9555. + if (!sc->sc_dma) {
  9556. + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
  9557. + goto fail;
  9558. + }
  9559. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  9560. +
  9561. + /*
  9562. + * Reset the board and do the ``secret handshake''
  9563. + * to enable the crypto support. Then complete the
  9564. + * initialization procedure by setting up the interrupt
  9565. + * and hooking in to the system crypto support so we'll
  9566. + * get used for system services like the crypto device,
  9567. + * IPsec, RNG device, etc.
  9568. + */
  9569. + hifn_reset_board(sc, 0);
  9570. +
  9571. + if (hifn_enable_crypto(sc) != 0) {
  9572. + device_printf(sc->sc_dev, "crypto enabling failed\n");
  9573. + goto fail;
  9574. + }
  9575. + hifn_reset_puc(sc);
  9576. +
  9577. + hifn_init_dma(sc);
  9578. + hifn_init_pci_registers(sc);
  9579. +
  9580. + pci_set_master(sc->sc_pcidev);
  9581. +
  9582. + /* XXX can't dynamically determine ram type for 795x; force dram */
  9583. + if (sc->sc_flags & HIFN_IS_7956)
  9584. + sc->sc_drammodel = 1;
  9585. + else if (hifn_ramtype(sc))
  9586. + goto fail;
  9587. +
  9588. + if (sc->sc_drammodel == 0)
  9589. + hifn_sramsize(sc);
  9590. + else
  9591. + hifn_dramsize(sc);
  9592. +
  9593. + /*
  9594. + * Workaround for NetSec 7751 rev A: half ram size because two
  9595. + * of the address lines were left floating
  9596. + */
  9597. + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
  9598. + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
  9599. + pci_get_revid(dev) == 0x61) /*XXX???*/
  9600. + sc->sc_ramsize >>= 1;
  9601. +
  9602. + /*
  9603. + * Arrange the interrupt line.
  9604. + */
  9605. + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
  9606. + if (rc) {
  9607. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  9608. + goto fail;
  9609. + }
  9610. + sc->sc_irq = dev->irq;
  9611. +
  9612. + hifn_sessions(sc);
  9613. +
  9614. + /*
  9615. + * NB: Keep only the low 16 bits; this masks the chip id
  9616. + * from the 7951.
  9617. + */
  9618. + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
  9619. +
  9620. + rseg = sc->sc_ramsize / 1024;
  9621. + rbase = 'K';
  9622. + if (sc->sc_ramsize >= (1024 * 1024)) {
  9623. + rbase = 'M';
  9624. + rseg /= 1024;
  9625. + }
  9626. + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
  9627. + hifn_partname(sc), rev,
  9628. + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
  9629. + if (sc->sc_flags & HIFN_IS_7956)
  9630. + printf(", pll=0x%x<%s clk, %ux mult>",
  9631. + sc->sc_pllconfig,
  9632. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  9633. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  9634. + printf("\n");
  9635. +
  9636. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  9637. + if (sc->sc_cid < 0) {
  9638. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  9639. + goto fail;
  9640. + }
  9641. +
  9642. + WRITE_REG_0(sc, HIFN_0_PUCNFG,
  9643. + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
  9644. + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  9645. +
  9646. + switch (ena) {
  9647. + case HIFN_PUSTAT_ENA_2:
  9648. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  9649. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  9650. + if (sc->sc_flags & HIFN_HAS_AES)
  9651. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  9652. + /*FALLTHROUGH*/
  9653. + case HIFN_PUSTAT_ENA_1:
  9654. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  9655. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  9656. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  9657. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  9658. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  9659. + break;
  9660. + }
  9661. +
  9662. + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
  9663. + hifn_init_pubrng(sc);
  9664. +
  9665. + init_timer(&sc->sc_tickto);
  9666. + sc->sc_tickto.function = hifn_tick;
  9667. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  9668. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  9669. +
  9670. + return (0);
  9671. +
  9672. +fail:
  9673. + if (sc->sc_cid >= 0)
  9674. + crypto_unregister_all(sc->sc_cid);
  9675. + if (sc->sc_irq != -1)
  9676. + free_irq(sc->sc_irq, sc);
  9677. + if (sc->sc_dma) {
  9678. + /* Turn off DMA polling */
  9679. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9680. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9681. +
  9682. + pci_free_consistent(sc->sc_pcidev,
  9683. + sizeof(*sc->sc_dma),
  9684. + sc->sc_dma, sc->sc_dma_physaddr);
  9685. + }
  9686. + kfree(sc);
  9687. + return (-ENXIO);
  9688. +}
  9689. +
  9690. +/*
  9691. + * Detach an interface that successfully probed.
  9692. + */
  9693. +static void
  9694. +hifn_remove(struct pci_dev *dev)
  9695. +{
  9696. + struct hifn_softc *sc = pci_get_drvdata(dev);
  9697. + unsigned long l_flags;
  9698. +
  9699. + DPRINTF("%s()\n", __FUNCTION__);
  9700. +
  9701. + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
  9702. +
  9703. + /* disable interrupts */
  9704. + HIFN_LOCK(sc);
  9705. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  9706. + HIFN_UNLOCK(sc);
  9707. +
  9708. + /*XXX other resources */
  9709. + del_timer_sync(&sc->sc_tickto);
  9710. +
  9711. + /* Turn off DMA polling */
  9712. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9713. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9714. +
  9715. + crypto_unregister_all(sc->sc_cid);
  9716. +
  9717. + free_irq(sc->sc_irq, sc);
  9718. +
  9719. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  9720. + sc->sc_dma, sc->sc_dma_physaddr);
  9721. +}
  9722. +
  9723. +
  9724. +static int
  9725. +hifn_init_pubrng(struct hifn_softc *sc)
  9726. +{
  9727. + int i;
  9728. +
  9729. + DPRINTF("%s()\n", __FUNCTION__);
  9730. +
  9731. + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
  9732. + /* Reset 7951 public key/rng engine */
  9733. + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
  9734. + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
  9735. +
  9736. + for (i = 0; i < 100; i++) {
  9737. + DELAY(1000);
  9738. + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
  9739. + HIFN_PUBRST_RESET) == 0)
  9740. + break;
  9741. + }
  9742. +
  9743. + if (i == 100) {
  9744. + device_printf(sc->sc_dev, "public key init failed\n");
  9745. + return (1);
  9746. + }
  9747. + }
  9748. +
  9749. + /* Enable the rng, if available */
  9750. +#ifdef CONFIG_OCF_RANDOMHARVEST
  9751. + if (sc->sc_flags & HIFN_HAS_RNG) {
  9752. + if (sc->sc_flags & HIFN_IS_7811) {
  9753. + u_int32_t r;
  9754. + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
  9755. + if (r & HIFN_7811_RNGENA_ENA) {
  9756. + r &= ~HIFN_7811_RNGENA_ENA;
  9757. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  9758. + }
  9759. + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
  9760. + HIFN_7811_RNGCFG_DEFL);
  9761. + r |= HIFN_7811_RNGENA_ENA;
  9762. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  9763. + } else
  9764. + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
  9765. + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
  9766. + HIFN_RNGCFG_ENA);
  9767. +
  9768. + sc->sc_rngfirst = 1;
  9769. + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
  9770. + }
  9771. +#endif
  9772. +
  9773. + /* Enable public key engine, if available */
  9774. + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
  9775. + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
  9776. + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
  9777. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  9778. +#ifdef HIFN_VULCANDEV
  9779. + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
  9780. + UID_ROOT, GID_WHEEL, 0666,
  9781. + "vulcanpk");
  9782. + sc->sc_pkdev->si_drv1 = sc;
  9783. +#endif
  9784. + }
  9785. +
  9786. + return (0);
  9787. +}
  9788. +
  9789. +#ifdef CONFIG_OCF_RANDOMHARVEST
  9790. +static int
  9791. +hifn_read_random(void *arg, u_int32_t *buf, int len)
  9792. +{
  9793. + struct hifn_softc *sc = (struct hifn_softc *) arg;
  9794. + u_int32_t sts;
  9795. + int i, rc = 0;
  9796. +
  9797. + if (len <= 0)
  9798. + return rc;
  9799. +
  9800. + if (sc->sc_flags & HIFN_IS_7811) {
  9801. + /* ONLY VALID ON 7811!!!! */
  9802. + for (i = 0; i < 5; i++) {
  9803. + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
  9804. + if (sts & HIFN_7811_RNGSTS_UFL) {
  9805. + device_printf(sc->sc_dev,
  9806. + "RNG underflow: disabling\n");
  9807. + /* DAVIDM perhaps return -1 */
  9808. + break;
  9809. + }
  9810. + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
  9811. + break;
  9812. +
  9813. + /*
  9814. + * There are at least two words in the RNG FIFO
  9815. + * at this point.
  9816. + */
  9817. + if (rc < len)
  9818. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  9819. + if (rc < len)
  9820. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  9821. + }
  9822. + } else
  9823. + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
  9824. +
  9825. + /* NB: discard first data read */
  9826. + if (sc->sc_rngfirst) {
  9827. + sc->sc_rngfirst = 0;
  9828. + rc = 0;
  9829. + }
  9830. +
  9831. + return(rc);
  9832. +}
  9833. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  9834. +
  9835. +static void
  9836. +hifn_puc_wait(struct hifn_softc *sc)
  9837. +{
  9838. + int i;
  9839. + int reg = HIFN_0_PUCTRL;
  9840. +
  9841. + if (sc->sc_flags & HIFN_IS_7956) {
  9842. + reg = HIFN_0_PUCTRL2;
  9843. + }
  9844. +
  9845. + for (i = 5000; i > 0; i--) {
  9846. + DELAY(1);
  9847. + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
  9848. + break;
  9849. + }
  9850. + if (!i)
  9851. + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
  9852. + READ_REG_0(sc, HIFN_0_PUCTRL));
  9853. +}
  9854. +
  9855. +/*
  9856. + * Reset the processing unit.
  9857. + */
  9858. +static void
  9859. +hifn_reset_puc(struct hifn_softc *sc)
  9860. +{
  9861. + /* Reset processing unit */
  9862. + int reg = HIFN_0_PUCTRL;
  9863. +
  9864. + if (sc->sc_flags & HIFN_IS_7956) {
  9865. + reg = HIFN_0_PUCTRL2;
  9866. + }
  9867. + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
  9868. +
  9869. + hifn_puc_wait(sc);
  9870. +}
  9871. +
  9872. +/*
  9873. + * Set the Retry and TRDY registers; note that we set them to
  9874. + * zero because the 7811 locks up when forced to retry (section
  9875. + * 3.6 of "Specification Update SU-0014-04". Not clear if we
  9876. + * should do this for all Hifn parts, but it doesn't seem to hurt.
  9877. + */
  9878. +static void
  9879. +hifn_set_retry(struct hifn_softc *sc)
  9880. +{
  9881. + DPRINTF("%s()\n", __FUNCTION__);
  9882. + /* NB: RETRY only responds to 8-bit reads/writes */
  9883. + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
  9884. + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
  9885. +}
  9886. +
  9887. +/*
  9888. + * Resets the board. Values in the regesters are left as is
  9889. + * from the reset (i.e. initial values are assigned elsewhere).
  9890. + */
  9891. +static void
  9892. +hifn_reset_board(struct hifn_softc *sc, int full)
  9893. +{
  9894. + u_int32_t reg;
  9895. +
  9896. + DPRINTF("%s()\n", __FUNCTION__);
  9897. + /*
  9898. + * Set polling in the DMA configuration register to zero. 0x7 avoids
  9899. + * resetting the board and zeros out the other fields.
  9900. + */
  9901. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9902. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9903. +
  9904. + /*
  9905. + * Now that polling has been disabled, we have to wait 1 ms
  9906. + * before resetting the board.
  9907. + */
  9908. + DELAY(1000);
  9909. +
  9910. + /* Reset the DMA unit */
  9911. + if (full) {
  9912. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
  9913. + DELAY(1000);
  9914. + } else {
  9915. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
  9916. + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
  9917. + hifn_reset_puc(sc);
  9918. + }
  9919. +
  9920. + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
  9921. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  9922. +
  9923. + /* Bring dma unit out of reset */
  9924. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  9925. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  9926. +
  9927. + hifn_puc_wait(sc);
  9928. + hifn_set_retry(sc);
  9929. +
  9930. + if (sc->sc_flags & HIFN_IS_7811) {
  9931. + for (reg = 0; reg < 1000; reg++) {
  9932. + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
  9933. + HIFN_MIPSRST_CRAMINIT)
  9934. + break;
  9935. + DELAY(1000);
  9936. + }
  9937. + if (reg == 1000)
  9938. + device_printf(sc->sc_dev, ": cram init timeout\n");
  9939. + } else {
  9940. + /* set up DMA configuration register #2 */
  9941. + /* turn off all PK and BAR0 swaps */
  9942. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
  9943. + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
  9944. + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
  9945. + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
  9946. + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
  9947. + }
  9948. +}
  9949. +
  9950. +static u_int32_t
  9951. +hifn_next_signature(u_int32_t a, u_int cnt)
  9952. +{
  9953. + int i;
  9954. + u_int32_t v;
  9955. +
  9956. + for (i = 0; i < cnt; i++) {
  9957. +
  9958. + /* get the parity */
  9959. + v = a & 0x80080125;
  9960. + v ^= v >> 16;
  9961. + v ^= v >> 8;
  9962. + v ^= v >> 4;
  9963. + v ^= v >> 2;
  9964. + v ^= v >> 1;
  9965. +
  9966. + a = (v & 1) ^ (a << 1);
  9967. + }
  9968. +
  9969. + return a;
  9970. +}
  9971. +
  9972. +
  9973. +/*
  9974. + * Checks to see if crypto is already enabled. If crypto isn't enable,
  9975. + * "hifn_enable_crypto" is called to enable it. The check is important,
  9976. + * as enabling crypto twice will lock the board.
  9977. + */
  9978. +static int
  9979. +hifn_enable_crypto(struct hifn_softc *sc)
  9980. +{
  9981. + u_int32_t dmacfg, ramcfg, encl, addr, i;
  9982. + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  9983. + 0x00, 0x00, 0x00, 0x00 };
  9984. +
  9985. + DPRINTF("%s()\n", __FUNCTION__);
  9986. +
  9987. + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  9988. + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
  9989. +
  9990. + /*
  9991. + * The RAM config register's encrypt level bit needs to be set before
  9992. + * every read performed on the encryption level register.
  9993. + */
  9994. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  9995. +
  9996. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  9997. +
  9998. + /*
  9999. + * Make sure we don't re-unlock. Two unlocks kills chip until the
  10000. + * next reboot.
  10001. + */
  10002. + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
  10003. +#ifdef HIFN_DEBUG
  10004. + if (hifn_debug)
  10005. + device_printf(sc->sc_dev,
  10006. + "Strong crypto already enabled!\n");
  10007. +#endif
  10008. + goto report;
  10009. + }
  10010. +
  10011. + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
  10012. +#ifdef HIFN_DEBUG
  10013. + if (hifn_debug)
  10014. + device_printf(sc->sc_dev,
  10015. + "Unknown encryption level 0x%x\n", encl);
  10016. +#endif
  10017. + return 1;
  10018. + }
  10019. +
  10020. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
  10021. + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  10022. + DELAY(1000);
  10023. + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
  10024. + DELAY(1000);
  10025. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
  10026. + DELAY(1000);
  10027. +
  10028. + for (i = 0; i <= 12; i++) {
  10029. + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
  10030. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
  10031. +
  10032. + DELAY(1000);
  10033. + }
  10034. +
  10035. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  10036. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  10037. +
  10038. +#ifdef HIFN_DEBUG
  10039. + if (hifn_debug) {
  10040. + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
  10041. + device_printf(sc->sc_dev, "Engine is permanently "
  10042. + "locked until next system reset!\n");
  10043. + else
  10044. + device_printf(sc->sc_dev, "Engine enabled "
  10045. + "successfully!\n");
  10046. + }
  10047. +#endif
  10048. +
  10049. +report:
  10050. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
  10051. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
  10052. +
  10053. + switch (encl) {
  10054. + case HIFN_PUSTAT_ENA_1:
  10055. + case HIFN_PUSTAT_ENA_2:
  10056. + break;
  10057. + case HIFN_PUSTAT_ENA_0:
  10058. + default:
  10059. + device_printf(sc->sc_dev, "disabled\n");
  10060. + break;
  10061. + }
  10062. +
  10063. + return 0;
  10064. +}
  10065. +
  10066. +/*
  10067. + * Give initial values to the registers listed in the "Register Space"
  10068. + * section of the HIFN Software Development reference manual.
  10069. + */
  10070. +static void
  10071. +hifn_init_pci_registers(struct hifn_softc *sc)
  10072. +{
  10073. + DPRINTF("%s()\n", __FUNCTION__);
  10074. +
  10075. + /* write fixed values needed by the Initialization registers */
  10076. + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
  10077. + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
  10078. + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
  10079. +
  10080. + /* write all 4 ring address registers */
  10081. + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
  10082. + offsetof(struct hifn_dma, cmdr[0]));
  10083. + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
  10084. + offsetof(struct hifn_dma, srcr[0]));
  10085. + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
  10086. + offsetof(struct hifn_dma, dstr[0]));
  10087. + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
  10088. + offsetof(struct hifn_dma, resr[0]));
  10089. +
  10090. + DELAY(2000);
  10091. +
  10092. + /* write status register */
  10093. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  10094. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
  10095. + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
  10096. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
  10097. + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
  10098. + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
  10099. + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
  10100. + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
  10101. + HIFN_DMACSR_S_WAIT |
  10102. + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
  10103. + HIFN_DMACSR_C_WAIT |
  10104. + HIFN_DMACSR_ENGINE |
  10105. + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
  10106. + HIFN_DMACSR_PUBDONE : 0) |
  10107. + ((sc->sc_flags & HIFN_IS_7811) ?
  10108. + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
  10109. +
  10110. + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
  10111. + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
  10112. + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
  10113. + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
  10114. + ((sc->sc_flags & HIFN_IS_7811) ?
  10115. + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
  10116. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  10117. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  10118. +
  10119. +
  10120. + if (sc->sc_flags & HIFN_IS_7956) {
  10121. + u_int32_t pll;
  10122. +
  10123. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  10124. + HIFN_PUCNFG_TCALLPHASES |
  10125. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
  10126. +
  10127. + /* turn off the clocks and insure bypass is set */
  10128. + pll = READ_REG_1(sc, HIFN_1_PLL);
  10129. + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
  10130. + | HIFN_PLL_BP | HIFN_PLL_MBSET;
  10131. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  10132. + DELAY(10*1000); /* 10ms */
  10133. +
  10134. + /* change configuration */
  10135. + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
  10136. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  10137. + DELAY(10*1000); /* 10ms */
  10138. +
  10139. + /* disable bypass */
  10140. + pll &= ~HIFN_PLL_BP;
  10141. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  10142. + /* enable clocks with new configuration */
  10143. + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
  10144. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  10145. + } else {
  10146. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  10147. + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
  10148. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
  10149. + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
  10150. + }
  10151. +
  10152. + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
  10153. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  10154. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
  10155. + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
  10156. + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
  10157. +}
  10158. +
  10159. +/*
  10160. + * The maximum number of sessions supported by the card
  10161. + * is dependent on the amount of context ram, which
  10162. + * encryption algorithms are enabled, and how compression
  10163. + * is configured. This should be configured before this
  10164. + * routine is called.
  10165. + */
  10166. +static void
  10167. +hifn_sessions(struct hifn_softc *sc)
  10168. +{
  10169. + u_int32_t pucnfg;
  10170. + int ctxsize;
  10171. +
  10172. + DPRINTF("%s()\n", __FUNCTION__);
  10173. +
  10174. + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  10175. +
  10176. + if (pucnfg & HIFN_PUCNFG_COMPSING) {
  10177. + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
  10178. + ctxsize = 128;
  10179. + else
  10180. + ctxsize = 512;
  10181. + /*
  10182. + * 7955/7956 has internal context memory of 32K
  10183. + */
  10184. + if (sc->sc_flags & HIFN_IS_7956)
  10185. + sc->sc_maxses = 32768 / ctxsize;
  10186. + else
  10187. + sc->sc_maxses = 1 +
  10188. + ((sc->sc_ramsize - 32768) / ctxsize);
  10189. + } else
  10190. + sc->sc_maxses = sc->sc_ramsize / 16384;
  10191. +
  10192. + if (sc->sc_maxses > 2048)
  10193. + sc->sc_maxses = 2048;
  10194. +}
  10195. +
  10196. +/*
  10197. + * Determine ram type (sram or dram). Board should be just out of a reset
  10198. + * state when this is called.
  10199. + */
  10200. +static int
  10201. +hifn_ramtype(struct hifn_softc *sc)
  10202. +{
  10203. + u_int8_t data[8], dataexpect[8];
  10204. + int i;
  10205. +
  10206. + for (i = 0; i < sizeof(data); i++)
  10207. + data[i] = dataexpect[i] = 0x55;
  10208. + if (hifn_writeramaddr(sc, 0, data))
  10209. + return (-1);
  10210. + if (hifn_readramaddr(sc, 0, data))
  10211. + return (-1);
  10212. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  10213. + sc->sc_drammodel = 1;
  10214. + return (0);
  10215. + }
  10216. +
  10217. + for (i = 0; i < sizeof(data); i++)
  10218. + data[i] = dataexpect[i] = 0xaa;
  10219. + if (hifn_writeramaddr(sc, 0, data))
  10220. + return (-1);
  10221. + if (hifn_readramaddr(sc, 0, data))
  10222. + return (-1);
  10223. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  10224. + sc->sc_drammodel = 1;
  10225. + return (0);
  10226. + }
  10227. +
  10228. + return (0);
  10229. +}
  10230. +
  10231. +#define HIFN_SRAM_MAX (32 << 20)
  10232. +#define HIFN_SRAM_STEP_SIZE 16384
  10233. +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
  10234. +
  10235. +static int
  10236. +hifn_sramsize(struct hifn_softc *sc)
  10237. +{
  10238. + u_int32_t a;
  10239. + u_int8_t data[8];
  10240. + u_int8_t dataexpect[sizeof(data)];
  10241. + int32_t i;
  10242. +
  10243. + for (i = 0; i < sizeof(data); i++)
  10244. + data[i] = dataexpect[i] = i ^ 0x5a;
  10245. +
  10246. + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
  10247. + a = i * HIFN_SRAM_STEP_SIZE;
  10248. + bcopy(&i, data, sizeof(i));
  10249. + hifn_writeramaddr(sc, a, data);
  10250. + }
  10251. +
  10252. + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
  10253. + a = i * HIFN_SRAM_STEP_SIZE;
  10254. + bcopy(&i, dataexpect, sizeof(i));
  10255. + if (hifn_readramaddr(sc, a, data) < 0)
  10256. + return (0);
  10257. + if (bcmp(data, dataexpect, sizeof(data)) != 0)
  10258. + return (0);
  10259. + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
  10260. + }
  10261. +
  10262. + return (0);
  10263. +}
  10264. +
  10265. +/*
  10266. + * XXX For dram boards, one should really try all of the
  10267. + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
  10268. + * is already set up correctly.
  10269. + */
  10270. +static int
  10271. +hifn_dramsize(struct hifn_softc *sc)
  10272. +{
  10273. + u_int32_t cnfg;
  10274. +
  10275. + if (sc->sc_flags & HIFN_IS_7956) {
  10276. + /*
  10277. + * 7955/7956 have a fixed internal ram of only 32K.
  10278. + */
  10279. + sc->sc_ramsize = 32768;
  10280. + } else {
  10281. + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
  10282. + HIFN_PUCNFG_DRAMMASK;
  10283. + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
  10284. + }
  10285. + return (0);
  10286. +}
  10287. +
  10288. +static void
  10289. +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
  10290. +{
  10291. + struct hifn_dma *dma = sc->sc_dma;
  10292. +
  10293. + DPRINTF("%s()\n", __FUNCTION__);
  10294. +
  10295. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  10296. + dma->cmdi = 0;
  10297. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10298. + wmb();
  10299. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  10300. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  10301. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10302. + }
  10303. + *cmdp = dma->cmdi++;
  10304. + dma->cmdk = dma->cmdi;
  10305. +
  10306. + if (dma->srci == HIFN_D_SRC_RSIZE) {
  10307. + dma->srci = 0;
  10308. + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10309. + wmb();
  10310. + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
  10311. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  10312. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10313. + }
  10314. + *srcp = dma->srci++;
  10315. + dma->srck = dma->srci;
  10316. +
  10317. + if (dma->dsti == HIFN_D_DST_RSIZE) {
  10318. + dma->dsti = 0;
  10319. + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10320. + wmb();
  10321. + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
  10322. + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
  10323. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10324. + }
  10325. + *dstp = dma->dsti++;
  10326. + dma->dstk = dma->dsti;
  10327. +
  10328. + if (dma->resi == HIFN_D_RES_RSIZE) {
  10329. + dma->resi = 0;
  10330. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10331. + wmb();
  10332. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  10333. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  10334. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10335. + }
  10336. + *resp = dma->resi++;
  10337. + dma->resk = dma->resi;
  10338. +}
  10339. +
  10340. +static int
  10341. +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  10342. +{
  10343. + struct hifn_dma *dma = sc->sc_dma;
  10344. + hifn_base_command_t wc;
  10345. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  10346. + int r, cmdi, resi, srci, dsti;
  10347. +
  10348. + DPRINTF("%s()\n", __FUNCTION__);
  10349. +
  10350. + wc.masks = htole16(3 << 13);
  10351. + wc.session_num = htole16(addr >> 14);
  10352. + wc.total_source_count = htole16(8);
  10353. + wc.total_dest_count = htole16(addr & 0x3fff);
  10354. +
  10355. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  10356. +
  10357. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  10358. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  10359. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  10360. +
  10361. + /* build write command */
  10362. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  10363. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
  10364. + bcopy(data, &dma->test_src, sizeof(dma->test_src));
  10365. +
  10366. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
  10367. + + offsetof(struct hifn_dma, test_src));
  10368. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
  10369. + + offsetof(struct hifn_dma, test_dst));
  10370. +
  10371. + dma->cmdr[cmdi].l = htole32(16 | masks);
  10372. + dma->srcr[srci].l = htole32(8 | masks);
  10373. + dma->dstr[dsti].l = htole32(4 | masks);
  10374. + dma->resr[resi].l = htole32(4 | masks);
  10375. +
  10376. + for (r = 10000; r >= 0; r--) {
  10377. + DELAY(10);
  10378. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  10379. + break;
  10380. + }
  10381. + if (r == 0) {
  10382. + device_printf(sc->sc_dev, "writeramaddr -- "
  10383. + "result[%d](addr %d) still valid\n", resi, addr);
  10384. + r = -1;
  10385. + return (-1);
  10386. + } else
  10387. + r = 0;
  10388. +
  10389. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  10390. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  10391. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  10392. +
  10393. + return (r);
  10394. +}
  10395. +
  10396. +static int
  10397. +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  10398. +{
  10399. + struct hifn_dma *dma = sc->sc_dma;
  10400. + hifn_base_command_t rc;
  10401. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  10402. + int r, cmdi, srci, dsti, resi;
  10403. +
  10404. + DPRINTF("%s()\n", __FUNCTION__);
  10405. +
  10406. + rc.masks = htole16(2 << 13);
  10407. + rc.session_num = htole16(addr >> 14);
  10408. + rc.total_source_count = htole16(addr & 0x3fff);
  10409. + rc.total_dest_count = htole16(8);
  10410. +
  10411. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  10412. +
  10413. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  10414. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  10415. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  10416. +
  10417. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  10418. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
  10419. +
  10420. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
  10421. + offsetof(struct hifn_dma, test_src));
  10422. + dma->test_src = 0;
  10423. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
  10424. + offsetof(struct hifn_dma, test_dst));
  10425. + dma->test_dst = 0;
  10426. + dma->cmdr[cmdi].l = htole32(8 | masks);
  10427. + dma->srcr[srci].l = htole32(8 | masks);
  10428. + dma->dstr[dsti].l = htole32(8 | masks);
  10429. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
  10430. +
  10431. + for (r = 10000; r >= 0; r--) {
  10432. + DELAY(10);
  10433. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  10434. + break;
  10435. + }
  10436. + if (r == 0) {
  10437. + device_printf(sc->sc_dev, "readramaddr -- "
  10438. + "result[%d](addr %d) still valid\n", resi, addr);
  10439. + r = -1;
  10440. + } else {
  10441. + r = 0;
  10442. + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
  10443. + }
  10444. +
  10445. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  10446. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  10447. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  10448. +
  10449. + return (r);
  10450. +}
  10451. +
  10452. +/*
  10453. + * Initialize the descriptor rings.
  10454. + */
  10455. +static void
  10456. +hifn_init_dma(struct hifn_softc *sc)
  10457. +{
  10458. + struct hifn_dma *dma = sc->sc_dma;
  10459. + int i;
  10460. +
  10461. + DPRINTF("%s()\n", __FUNCTION__);
  10462. +
  10463. + hifn_set_retry(sc);
  10464. +
  10465. + /* initialize static pointer values */
  10466. + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
  10467. + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
  10468. + offsetof(struct hifn_dma, command_bufs[i][0]));
  10469. + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
  10470. + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
  10471. + offsetof(struct hifn_dma, result_bufs[i][0]));
  10472. +
  10473. + dma->cmdr[HIFN_D_CMD_RSIZE].p =
  10474. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
  10475. + dma->srcr[HIFN_D_SRC_RSIZE].p =
  10476. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
  10477. + dma->dstr[HIFN_D_DST_RSIZE].p =
  10478. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
  10479. + dma->resr[HIFN_D_RES_RSIZE].p =
  10480. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
  10481. +
  10482. + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
  10483. + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
  10484. + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
  10485. +}
  10486. +
  10487. +/*
  10488. + * Writes out the raw command buffer space. Returns the
  10489. + * command buffer size.
  10490. + */
  10491. +static u_int
  10492. +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
  10493. +{
  10494. + struct hifn_softc *sc = NULL;
  10495. + u_int8_t *buf_pos;
  10496. + hifn_base_command_t *base_cmd;
  10497. + hifn_mac_command_t *mac_cmd;
  10498. + hifn_crypt_command_t *cry_cmd;
  10499. + int using_mac, using_crypt, len, ivlen;
  10500. + u_int32_t dlen, slen;
  10501. +
  10502. + DPRINTF("%s()\n", __FUNCTION__);
  10503. +
  10504. + buf_pos = buf;
  10505. + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
  10506. + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
  10507. +
  10508. + base_cmd = (hifn_base_command_t *)buf_pos;
  10509. + base_cmd->masks = htole16(cmd->base_masks);
  10510. + slen = cmd->src_mapsize;
  10511. + if (cmd->sloplen)
  10512. + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
  10513. + else
  10514. + dlen = cmd->dst_mapsize;
  10515. + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
  10516. + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
  10517. + dlen >>= 16;
  10518. + slen >>= 16;
  10519. + base_cmd->session_num = htole16(
  10520. + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
  10521. + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
  10522. + buf_pos += sizeof(hifn_base_command_t);
  10523. +
  10524. + if (using_mac) {
  10525. + mac_cmd = (hifn_mac_command_t *)buf_pos;
  10526. + dlen = cmd->maccrd->crd_len;
  10527. + mac_cmd->source_count = htole16(dlen & 0xffff);
  10528. + dlen >>= 16;
  10529. + mac_cmd->masks = htole16(cmd->mac_masks |
  10530. + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
  10531. + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
  10532. + mac_cmd->reserved = 0;
  10533. + buf_pos += sizeof(hifn_mac_command_t);
  10534. + }
  10535. +
  10536. + if (using_crypt) {
  10537. + cry_cmd = (hifn_crypt_command_t *)buf_pos;
  10538. + dlen = cmd->enccrd->crd_len;
  10539. + cry_cmd->source_count = htole16(dlen & 0xffff);
  10540. + dlen >>= 16;
  10541. + cry_cmd->masks = htole16(cmd->cry_masks |
  10542. + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
  10543. + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
  10544. + cry_cmd->reserved = 0;
  10545. + buf_pos += sizeof(hifn_crypt_command_t);
  10546. + }
  10547. +
  10548. + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
  10549. + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
  10550. + buf_pos += HIFN_MAC_KEY_LENGTH;
  10551. + }
  10552. +
  10553. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
  10554. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  10555. + case HIFN_CRYPT_CMD_ALG_3DES:
  10556. + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
  10557. + buf_pos += HIFN_3DES_KEY_LENGTH;
  10558. + break;
  10559. + case HIFN_CRYPT_CMD_ALG_DES:
  10560. + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
  10561. + buf_pos += HIFN_DES_KEY_LENGTH;
  10562. + break;
  10563. + case HIFN_CRYPT_CMD_ALG_RC4:
  10564. + len = 256;
  10565. + do {
  10566. + int clen;
  10567. +
  10568. + clen = MIN(cmd->cklen, len);
  10569. + bcopy(cmd->ck, buf_pos, clen);
  10570. + len -= clen;
  10571. + buf_pos += clen;
  10572. + } while (len > 0);
  10573. + bzero(buf_pos, 4);
  10574. + buf_pos += 4;
  10575. + break;
  10576. + case HIFN_CRYPT_CMD_ALG_AES:
  10577. + /*
  10578. + * AES keys are variable 128, 192 and
  10579. + * 256 bits (16, 24 and 32 bytes).
  10580. + */
  10581. + bcopy(cmd->ck, buf_pos, cmd->cklen);
  10582. + buf_pos += cmd->cklen;
  10583. + break;
  10584. + }
  10585. + }
  10586. +
  10587. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
  10588. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  10589. + case HIFN_CRYPT_CMD_ALG_AES:
  10590. + ivlen = HIFN_AES_IV_LENGTH;
  10591. + break;
  10592. + default:
  10593. + ivlen = HIFN_IV_LENGTH;
  10594. + break;
  10595. + }
  10596. + bcopy(cmd->iv, buf_pos, ivlen);
  10597. + buf_pos += ivlen;
  10598. + }
  10599. +
  10600. + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
  10601. + bzero(buf_pos, 8);
  10602. + buf_pos += 8;
  10603. + }
  10604. +
  10605. + return (buf_pos - buf);
  10606. +}
  10607. +
  10608. +static int
  10609. +hifn_dmamap_aligned(struct hifn_operand *op)
  10610. +{
  10611. + struct hifn_softc *sc = NULL;
  10612. + int i;
  10613. +
  10614. + DPRINTF("%s()\n", __FUNCTION__);
  10615. +
  10616. + for (i = 0; i < op->nsegs; i++) {
  10617. + if (op->segs[i].ds_addr & 3)
  10618. + return (0);
  10619. + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
  10620. + return (0);
  10621. + }
  10622. + return (1);
  10623. +}
  10624. +
  10625. +static __inline int
  10626. +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
  10627. +{
  10628. + struct hifn_dma *dma = sc->sc_dma;
  10629. +
  10630. + if (++idx == HIFN_D_DST_RSIZE) {
  10631. + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
  10632. + HIFN_D_MASKDONEIRQ);
  10633. + HIFN_DSTR_SYNC(sc, idx,
  10634. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10635. + idx = 0;
  10636. + }
  10637. + return (idx);
  10638. +}
  10639. +
  10640. +static int
  10641. +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
  10642. +{
  10643. + struct hifn_dma *dma = sc->sc_dma;
  10644. + struct hifn_operand *dst = &cmd->dst;
  10645. + u_int32_t p, l;
  10646. + int idx, used = 0, i;
  10647. +
  10648. + DPRINTF("%s()\n", __FUNCTION__);
  10649. +
  10650. + idx = dma->dsti;
  10651. + for (i = 0; i < dst->nsegs - 1; i++) {
  10652. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  10653. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
  10654. + wmb();
  10655. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  10656. + HIFN_DSTR_SYNC(sc, idx,
  10657. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10658. + used++;
  10659. +
  10660. + idx = hifn_dmamap_dstwrap(sc, idx);
  10661. + }
  10662. +
  10663. + if (cmd->sloplen == 0) {
  10664. + p = dst->segs[i].ds_addr;
  10665. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  10666. + dst->segs[i].ds_len;
  10667. + } else {
  10668. + p = sc->sc_dma_physaddr +
  10669. + offsetof(struct hifn_dma, slop[cmd->slopidx]);
  10670. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  10671. + sizeof(u_int32_t);
  10672. +
  10673. + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
  10674. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  10675. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
  10676. + (dst->segs[i].ds_len - cmd->sloplen));
  10677. + wmb();
  10678. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  10679. + HIFN_DSTR_SYNC(sc, idx,
  10680. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10681. + used++;
  10682. +
  10683. + idx = hifn_dmamap_dstwrap(sc, idx);
  10684. + }
  10685. + }
  10686. + dma->dstr[idx].p = htole32(p);
  10687. + dma->dstr[idx].l = htole32(l);
  10688. + wmb();
  10689. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  10690. + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  10691. + used++;
  10692. +
  10693. + idx = hifn_dmamap_dstwrap(sc, idx);
  10694. +
  10695. + dma->dsti = idx;
  10696. + dma->dstu += used;
  10697. + return (idx);
  10698. +}
  10699. +
  10700. +static __inline int
  10701. +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
  10702. +{
  10703. + struct hifn_dma *dma = sc->sc_dma;
  10704. +
  10705. + if (++idx == HIFN_D_SRC_RSIZE) {
  10706. + dma->srcr[idx].l = htole32(HIFN_D_VALID |
  10707. + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
  10708. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  10709. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10710. + idx = 0;
  10711. + }
  10712. + return (idx);
  10713. +}
  10714. +
  10715. +static int
  10716. +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
  10717. +{
  10718. + struct hifn_dma *dma = sc->sc_dma;
  10719. + struct hifn_operand *src = &cmd->src;
  10720. + int idx, i;
  10721. + u_int32_t last = 0;
  10722. +
  10723. + DPRINTF("%s()\n", __FUNCTION__);
  10724. +
  10725. + idx = dma->srci;
  10726. + for (i = 0; i < src->nsegs; i++) {
  10727. + if (i == src->nsegs - 1)
  10728. + last = HIFN_D_LAST;
  10729. +
  10730. + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
  10731. + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
  10732. + HIFN_D_MASKDONEIRQ | last);
  10733. + wmb();
  10734. + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
  10735. + HIFN_SRCR_SYNC(sc, idx,
  10736. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10737. +
  10738. + idx = hifn_dmamap_srcwrap(sc, idx);
  10739. + }
  10740. + dma->srci = idx;
  10741. + dma->srcu += src->nsegs;
  10742. + return (idx);
  10743. +}
  10744. +
  10745. +
  10746. +static int
  10747. +hifn_crypto(
  10748. + struct hifn_softc *sc,
  10749. + struct hifn_command *cmd,
  10750. + struct cryptop *crp,
  10751. + int hint)
  10752. +{
  10753. + struct hifn_dma *dma = sc->sc_dma;
  10754. + u_int32_t cmdlen, csr;
  10755. + int cmdi, resi, err = 0;
  10756. + unsigned long l_flags;
  10757. +
  10758. + DPRINTF("%s()\n", __FUNCTION__);
  10759. +
  10760. + /*
  10761. + * need 1 cmd, and 1 res
  10762. + *
  10763. + * NB: check this first since it's easy.
  10764. + */
  10765. + HIFN_LOCK(sc);
  10766. + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
  10767. + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
  10768. +#ifdef HIFN_DEBUG
  10769. + if (hifn_debug) {
  10770. + device_printf(sc->sc_dev,
  10771. + "cmd/result exhaustion, cmdu %u resu %u\n",
  10772. + dma->cmdu, dma->resu);
  10773. + }
  10774. +#endif
  10775. + hifnstats.hst_nomem_cr++;
  10776. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  10777. + HIFN_UNLOCK(sc);
  10778. + return (ERESTART);
  10779. + }
  10780. +
  10781. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10782. + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
  10783. + hifnstats.hst_nomem_load++;
  10784. + err = ENOMEM;
  10785. + goto err_srcmap1;
  10786. + }
  10787. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  10788. + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
  10789. + hifnstats.hst_nomem_load++;
  10790. + err = ENOMEM;
  10791. + goto err_srcmap1;
  10792. + }
  10793. + } else {
  10794. + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
  10795. + hifnstats.hst_nomem_load++;
  10796. + err = ENOMEM;
  10797. + goto err_srcmap1;
  10798. + }
  10799. + }
  10800. +
  10801. + if (hifn_dmamap_aligned(&cmd->src)) {
  10802. + cmd->sloplen = cmd->src_mapsize & 3;
  10803. + cmd->dst = cmd->src;
  10804. + } else {
  10805. + if (crp->crp_flags & CRYPTO_F_IOV) {
  10806. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  10807. + err = EINVAL;
  10808. + goto err_srcmap;
  10809. + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10810. +#ifdef NOTYET
  10811. + int totlen, len;
  10812. + struct mbuf *m, *m0, *mlast;
  10813. +
  10814. + KASSERT(cmd->dst_m == cmd->src_m,
  10815. + ("hifn_crypto: dst_m initialized improperly"));
  10816. + hifnstats.hst_unaligned++;
  10817. + /*
  10818. + * Source is not aligned on a longword boundary.
  10819. + * Copy the data to insure alignment. If we fail
  10820. + * to allocate mbufs or clusters while doing this
  10821. + * we return ERESTART so the operation is requeued
  10822. + * at the crypto later, but only if there are
  10823. + * ops already posted to the hardware; otherwise we
  10824. + * have no guarantee that we'll be re-entered.
  10825. + */
  10826. + totlen = cmd->src_mapsize;
  10827. + if (cmd->src_m->m_flags & M_PKTHDR) {
  10828. + len = MHLEN;
  10829. + MGETHDR(m0, M_DONTWAIT, MT_DATA);
  10830. + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
  10831. + m_free(m0);
  10832. + m0 = NULL;
  10833. + }
  10834. + } else {
  10835. + len = MLEN;
  10836. + MGET(m0, M_DONTWAIT, MT_DATA);
  10837. + }
  10838. + if (m0 == NULL) {
  10839. + hifnstats.hst_nomem_mbuf++;
  10840. + err = dma->cmdu ? ERESTART : ENOMEM;
  10841. + goto err_srcmap;
  10842. + }
  10843. + if (totlen >= MINCLSIZE) {
  10844. + MCLGET(m0, M_DONTWAIT);
  10845. + if ((m0->m_flags & M_EXT) == 0) {
  10846. + hifnstats.hst_nomem_mcl++;
  10847. + err = dma->cmdu ? ERESTART : ENOMEM;
  10848. + m_freem(m0);
  10849. + goto err_srcmap;
  10850. + }
  10851. + len = MCLBYTES;
  10852. + }
  10853. + totlen -= len;
  10854. + m0->m_pkthdr.len = m0->m_len = len;
  10855. + mlast = m0;
  10856. +
  10857. + while (totlen > 0) {
  10858. + MGET(m, M_DONTWAIT, MT_DATA);
  10859. + if (m == NULL) {
  10860. + hifnstats.hst_nomem_mbuf++;
  10861. + err = dma->cmdu ? ERESTART : ENOMEM;
  10862. + m_freem(m0);
  10863. + goto err_srcmap;
  10864. + }
  10865. + len = MLEN;
  10866. + if (totlen >= MINCLSIZE) {
  10867. + MCLGET(m, M_DONTWAIT);
  10868. + if ((m->m_flags & M_EXT) == 0) {
  10869. + hifnstats.hst_nomem_mcl++;
  10870. + err = dma->cmdu ? ERESTART : ENOMEM;
  10871. + mlast->m_next = m;
  10872. + m_freem(m0);
  10873. + goto err_srcmap;
  10874. + }
  10875. + len = MCLBYTES;
  10876. + }
  10877. +
  10878. + m->m_len = len;
  10879. + m0->m_pkthdr.len += len;
  10880. + totlen -= len;
  10881. +
  10882. + mlast->m_next = m;
  10883. + mlast = m;
  10884. + }
  10885. + cmd->dst_m = m0;
  10886. +#else
  10887. + device_printf(sc->sc_dev,
  10888. + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
  10889. + __FILE__, __LINE__);
  10890. + err = EINVAL;
  10891. + goto err_srcmap;
  10892. +#endif
  10893. + } else {
  10894. + device_printf(sc->sc_dev,
  10895. + "%s,%d: unaligned contig buffers not implemented\n",
  10896. + __FILE__, __LINE__);
  10897. + err = EINVAL;
  10898. + goto err_srcmap;
  10899. + }
  10900. + }
  10901. +
  10902. + if (cmd->dst_map == NULL) {
  10903. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  10904. + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
  10905. + hifnstats.hst_nomem_map++;
  10906. + err = ENOMEM;
  10907. + goto err_dstmap1;
  10908. + }
  10909. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  10910. + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
  10911. + hifnstats.hst_nomem_load++;
  10912. + err = ENOMEM;
  10913. + goto err_dstmap1;
  10914. + }
  10915. + } else {
  10916. + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
  10917. + hifnstats.hst_nomem_load++;
  10918. + err = ENOMEM;
  10919. + goto err_dstmap1;
  10920. + }
  10921. + }
  10922. + }
  10923. +
  10924. +#ifdef HIFN_DEBUG
  10925. + if (hifn_debug) {
  10926. + device_printf(sc->sc_dev,
  10927. + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
  10928. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  10929. + READ_REG_1(sc, HIFN_1_DMA_IER),
  10930. + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
  10931. + cmd->src_nsegs, cmd->dst_nsegs);
  10932. + }
  10933. +#endif
  10934. +
  10935. +#if 0
  10936. + if (cmd->src_map == cmd->dst_map) {
  10937. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  10938. + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
  10939. + } else {
  10940. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  10941. + BUS_DMASYNC_PREWRITE);
  10942. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  10943. + BUS_DMASYNC_PREREAD);
  10944. + }
  10945. +#endif
  10946. +
  10947. + /*
  10948. + * need N src, and N dst
  10949. + */
  10950. + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
  10951. + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
  10952. +#ifdef HIFN_DEBUG
  10953. + if (hifn_debug) {
  10954. + device_printf(sc->sc_dev,
  10955. + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
  10956. + dma->srcu, cmd->src_nsegs,
  10957. + dma->dstu, cmd->dst_nsegs);
  10958. + }
  10959. +#endif
  10960. + hifnstats.hst_nomem_sd++;
  10961. + err = ERESTART;
  10962. + goto err_dstmap;
  10963. + }
  10964. +
  10965. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  10966. + dma->cmdi = 0;
  10967. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  10968. + wmb();
  10969. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  10970. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  10971. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10972. + }
  10973. + cmdi = dma->cmdi++;
  10974. + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
  10975. + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
  10976. +
  10977. + /* .p for command/result already set */
  10978. + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
  10979. + HIFN_D_MASKDONEIRQ);
  10980. + wmb();
  10981. + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
  10982. + HIFN_CMDR_SYNC(sc, cmdi,
  10983. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  10984. + dma->cmdu++;
  10985. +
  10986. + /*
  10987. + * We don't worry about missing an interrupt (which a "command wait"
  10988. + * interrupt salvages us from), unless there is more than one command
  10989. + * in the queue.
  10990. + */
  10991. + if (dma->cmdu > 1) {
  10992. + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
  10993. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  10994. + }
  10995. +
  10996. + hifnstats.hst_ipackets++;
  10997. + hifnstats.hst_ibytes += cmd->src_mapsize;
  10998. +
  10999. + hifn_dmamap_load_src(sc, cmd);
  11000. +
  11001. + /*
  11002. + * Unlike other descriptors, we don't mask done interrupt from
  11003. + * result descriptor.
  11004. + */
  11005. +#ifdef HIFN_DEBUG
  11006. + if (hifn_debug)
  11007. + device_printf(sc->sc_dev, "load res\n");
  11008. +#endif
  11009. + if (dma->resi == HIFN_D_RES_RSIZE) {
  11010. + dma->resi = 0;
  11011. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  11012. + wmb();
  11013. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  11014. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  11015. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11016. + }
  11017. + resi = dma->resi++;
  11018. + KASSERT(dma->hifn_commands[resi] == NULL,
  11019. + ("hifn_crypto: command slot %u busy", resi));
  11020. + dma->hifn_commands[resi] = cmd;
  11021. + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
  11022. + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
  11023. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
  11024. + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
  11025. + wmb();
  11026. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  11027. + sc->sc_curbatch++;
  11028. + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
  11029. + hifnstats.hst_maxbatch = sc->sc_curbatch;
  11030. + hifnstats.hst_totbatch++;
  11031. + } else {
  11032. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
  11033. + wmb();
  11034. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  11035. + sc->sc_curbatch = 0;
  11036. + }
  11037. + HIFN_RESR_SYNC(sc, resi,
  11038. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11039. + dma->resu++;
  11040. +
  11041. + if (cmd->sloplen)
  11042. + cmd->slopidx = resi;
  11043. +
  11044. + hifn_dmamap_load_dst(sc, cmd);
  11045. +
  11046. + csr = 0;
  11047. + if (sc->sc_c_busy == 0) {
  11048. + csr |= HIFN_DMACSR_C_CTRL_ENA;
  11049. + sc->sc_c_busy = 1;
  11050. + }
  11051. + if (sc->sc_s_busy == 0) {
  11052. + csr |= HIFN_DMACSR_S_CTRL_ENA;
  11053. + sc->sc_s_busy = 1;
  11054. + }
  11055. + if (sc->sc_r_busy == 0) {
  11056. + csr |= HIFN_DMACSR_R_CTRL_ENA;
  11057. + sc->sc_r_busy = 1;
  11058. + }
  11059. + if (sc->sc_d_busy == 0) {
  11060. + csr |= HIFN_DMACSR_D_CTRL_ENA;
  11061. + sc->sc_d_busy = 1;
  11062. + }
  11063. + if (csr)
  11064. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
  11065. +
  11066. +#ifdef HIFN_DEBUG
  11067. + if (hifn_debug) {
  11068. + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
  11069. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  11070. + READ_REG_1(sc, HIFN_1_DMA_IER));
  11071. + }
  11072. +#endif
  11073. +
  11074. + sc->sc_active = 5;
  11075. + HIFN_UNLOCK(sc);
  11076. + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
  11077. + return (err); /* success */
  11078. +
  11079. +err_dstmap:
  11080. + if (cmd->src_map != cmd->dst_map)
  11081. + pci_unmap_buf(sc, &cmd->dst);
  11082. +err_dstmap1:
  11083. +err_srcmap:
  11084. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  11085. + if (cmd->src_skb != cmd->dst_skb)
  11086. +#ifdef NOTYET
  11087. + m_freem(cmd->dst_m);
  11088. +#else
  11089. + device_printf(sc->sc_dev,
  11090. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  11091. + __FILE__, __LINE__);
  11092. +#endif
  11093. + }
  11094. + pci_unmap_buf(sc, &cmd->src);
  11095. +err_srcmap1:
  11096. + HIFN_UNLOCK(sc);
  11097. + return (err);
  11098. +}
  11099. +
  11100. +static void
  11101. +hifn_tick(unsigned long arg)
  11102. +{
  11103. + struct hifn_softc *sc;
  11104. + unsigned long l_flags;
  11105. +
  11106. + if (arg >= HIFN_MAX_CHIPS)
  11107. + return;
  11108. + sc = hifn_chip_idx[arg];
  11109. + if (!sc)
  11110. + return;
  11111. +
  11112. + HIFN_LOCK(sc);
  11113. + if (sc->sc_active == 0) {
  11114. + struct hifn_dma *dma = sc->sc_dma;
  11115. + u_int32_t r = 0;
  11116. +
  11117. + if (dma->cmdu == 0 && sc->sc_c_busy) {
  11118. + sc->sc_c_busy = 0;
  11119. + r |= HIFN_DMACSR_C_CTRL_DIS;
  11120. + }
  11121. + if (dma->srcu == 0 && sc->sc_s_busy) {
  11122. + sc->sc_s_busy = 0;
  11123. + r |= HIFN_DMACSR_S_CTRL_DIS;
  11124. + }
  11125. + if (dma->dstu == 0 && sc->sc_d_busy) {
  11126. + sc->sc_d_busy = 0;
  11127. + r |= HIFN_DMACSR_D_CTRL_DIS;
  11128. + }
  11129. + if (dma->resu == 0 && sc->sc_r_busy) {
  11130. + sc->sc_r_busy = 0;
  11131. + r |= HIFN_DMACSR_R_CTRL_DIS;
  11132. + }
  11133. + if (r)
  11134. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
  11135. + } else
  11136. + sc->sc_active--;
  11137. + HIFN_UNLOCK(sc);
  11138. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  11139. +}
  11140. +
  11141. +static irqreturn_t
  11142. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  11143. +hifn_intr(int irq, void *arg)
  11144. +#else
  11145. +hifn_intr(int irq, void *arg, struct pt_regs *regs)
  11146. +#endif
  11147. +{
  11148. + struct hifn_softc *sc = arg;
  11149. + struct hifn_dma *dma;
  11150. + u_int32_t dmacsr, restart;
  11151. + int i, u;
  11152. + unsigned long l_flags;
  11153. +
  11154. + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
  11155. +
  11156. + /* Nothing in the DMA unit interrupted */
  11157. + if ((dmacsr & sc->sc_dmaier) == 0)
  11158. + return IRQ_NONE;
  11159. +
  11160. + HIFN_LOCK(sc);
  11161. +
  11162. + dma = sc->sc_dma;
  11163. +
  11164. +#ifdef HIFN_DEBUG
  11165. + if (hifn_debug) {
  11166. + device_printf(sc->sc_dev,
  11167. + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
  11168. + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
  11169. + dma->cmdi, dma->srci, dma->dsti, dma->resi,
  11170. + dma->cmdk, dma->srck, dma->dstk, dma->resk,
  11171. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  11172. + }
  11173. +#endif
  11174. +
  11175. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
  11176. +
  11177. + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
  11178. + (dmacsr & HIFN_DMACSR_PUBDONE))
  11179. + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
  11180. + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
  11181. +
  11182. + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
  11183. + if (restart)
  11184. + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
  11185. +
  11186. + if (sc->sc_flags & HIFN_IS_7811) {
  11187. + if (dmacsr & HIFN_DMACSR_ILLR)
  11188. + device_printf(sc->sc_dev, "illegal read\n");
  11189. + if (dmacsr & HIFN_DMACSR_ILLW)
  11190. + device_printf(sc->sc_dev, "illegal write\n");
  11191. + }
  11192. +
  11193. + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
  11194. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
  11195. + if (restart) {
  11196. + device_printf(sc->sc_dev, "abort, resetting.\n");
  11197. + hifnstats.hst_abort++;
  11198. + hifn_abort(sc);
  11199. + HIFN_UNLOCK(sc);
  11200. + return IRQ_HANDLED;
  11201. + }
  11202. +
  11203. + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
  11204. + /*
  11205. + * If no slots to process and we receive a "waiting on
  11206. + * command" interrupt, we disable the "waiting on command"
  11207. + * (by clearing it).
  11208. + */
  11209. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  11210. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  11211. + }
  11212. +
  11213. + /* clear the rings */
  11214. + i = dma->resk; u = dma->resu;
  11215. + while (u != 0) {
  11216. + HIFN_RESR_SYNC(sc, i,
  11217. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  11218. + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
  11219. + HIFN_RESR_SYNC(sc, i,
  11220. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11221. + break;
  11222. + }
  11223. +
  11224. + if (i != HIFN_D_RES_RSIZE) {
  11225. + struct hifn_command *cmd;
  11226. + u_int8_t *macbuf = NULL;
  11227. +
  11228. + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
  11229. + cmd = dma->hifn_commands[i];
  11230. + KASSERT(cmd != NULL,
  11231. + ("hifn_intr: null command slot %u", i));
  11232. + dma->hifn_commands[i] = NULL;
  11233. +
  11234. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  11235. + macbuf = dma->result_bufs[i];
  11236. + macbuf += 12;
  11237. + }
  11238. +
  11239. + hifn_callback(sc, cmd, macbuf);
  11240. + hifnstats.hst_opackets++;
  11241. + u--;
  11242. + }
  11243. +
  11244. + if (++i == (HIFN_D_RES_RSIZE + 1))
  11245. + i = 0;
  11246. + }
  11247. + dma->resk = i; dma->resu = u;
  11248. +
  11249. + i = dma->srck; u = dma->srcu;
  11250. + while (u != 0) {
  11251. + if (i == HIFN_D_SRC_RSIZE)
  11252. + i = 0;
  11253. + HIFN_SRCR_SYNC(sc, i,
  11254. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  11255. + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
  11256. + HIFN_SRCR_SYNC(sc, i,
  11257. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11258. + break;
  11259. + }
  11260. + i++, u--;
  11261. + }
  11262. + dma->srck = i; dma->srcu = u;
  11263. +
  11264. + i = dma->cmdk; u = dma->cmdu;
  11265. + while (u != 0) {
  11266. + HIFN_CMDR_SYNC(sc, i,
  11267. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  11268. + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
  11269. + HIFN_CMDR_SYNC(sc, i,
  11270. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11271. + break;
  11272. + }
  11273. + if (i != HIFN_D_CMD_RSIZE) {
  11274. + u--;
  11275. + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
  11276. + }
  11277. + if (++i == (HIFN_D_CMD_RSIZE + 1))
  11278. + i = 0;
  11279. + }
  11280. + dma->cmdk = i; dma->cmdu = u;
  11281. +
  11282. + HIFN_UNLOCK(sc);
  11283. +
  11284. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  11285. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  11286. +#ifdef HIFN_DEBUG
  11287. + if (hifn_debug)
  11288. + device_printf(sc->sc_dev,
  11289. + "wakeup crypto (%x) u %d/%d/%d/%d\n",
  11290. + sc->sc_needwakeup,
  11291. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  11292. +#endif
  11293. + sc->sc_needwakeup &= ~wakeup;
  11294. + crypto_unblock(sc->sc_cid, wakeup);
  11295. + }
  11296. +
  11297. + return IRQ_HANDLED;
  11298. +}
  11299. +
  11300. +/*
  11301. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  11302. + * contains our registration id, and should contain an encoded session
  11303. + * id on successful allocation.
  11304. + */
  11305. +static int
  11306. +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  11307. +{
  11308. + struct hifn_softc *sc = device_get_softc(dev);
  11309. + struct cryptoini *c;
  11310. + int mac = 0, cry = 0, sesn;
  11311. + struct hifn_session *ses = NULL;
  11312. + unsigned long l_flags;
  11313. +
  11314. + DPRINTF("%s()\n", __FUNCTION__);
  11315. +
  11316. + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
  11317. + if (sidp == NULL || cri == NULL || sc == NULL) {
  11318. + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
  11319. + return (EINVAL);
  11320. + }
  11321. +
  11322. + HIFN_LOCK(sc);
  11323. + if (sc->sc_sessions == NULL) {
  11324. + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
  11325. + SLAB_ATOMIC);
  11326. + if (ses == NULL) {
  11327. + HIFN_UNLOCK(sc);
  11328. + return (ENOMEM);
  11329. + }
  11330. + sesn = 0;
  11331. + sc->sc_nsessions = 1;
  11332. + } else {
  11333. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  11334. + if (!sc->sc_sessions[sesn].hs_used) {
  11335. + ses = &sc->sc_sessions[sesn];
  11336. + break;
  11337. + }
  11338. + }
  11339. +
  11340. + if (ses == NULL) {
  11341. + sesn = sc->sc_nsessions;
  11342. + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
  11343. + SLAB_ATOMIC);
  11344. + if (ses == NULL) {
  11345. + HIFN_UNLOCK(sc);
  11346. + return (ENOMEM);
  11347. + }
  11348. + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
  11349. + bzero(sc->sc_sessions, sesn * sizeof(*ses));
  11350. + kfree(sc->sc_sessions);
  11351. + sc->sc_sessions = ses;
  11352. + ses = &sc->sc_sessions[sesn];
  11353. + sc->sc_nsessions++;
  11354. + }
  11355. + }
  11356. + HIFN_UNLOCK(sc);
  11357. +
  11358. + bzero(ses, sizeof(*ses));
  11359. + ses->hs_used = 1;
  11360. +
  11361. + for (c = cri; c != NULL; c = c->cri_next) {
  11362. + switch (c->cri_alg) {
  11363. + case CRYPTO_MD5:
  11364. + case CRYPTO_SHA1:
  11365. + case CRYPTO_MD5_HMAC:
  11366. + case CRYPTO_SHA1_HMAC:
  11367. + if (mac) {
  11368. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11369. + return (EINVAL);
  11370. + }
  11371. + mac = 1;
  11372. + ses->hs_mlen = c->cri_mlen;
  11373. + if (ses->hs_mlen == 0) {
  11374. + switch (c->cri_alg) {
  11375. + case CRYPTO_MD5:
  11376. + case CRYPTO_MD5_HMAC:
  11377. + ses->hs_mlen = 16;
  11378. + break;
  11379. + case CRYPTO_SHA1:
  11380. + case CRYPTO_SHA1_HMAC:
  11381. + ses->hs_mlen = 20;
  11382. + break;
  11383. + }
  11384. + }
  11385. + break;
  11386. + case CRYPTO_DES_CBC:
  11387. + case CRYPTO_3DES_CBC:
  11388. + case CRYPTO_AES_CBC:
  11389. + /* XXX this may read fewer, does it matter? */
  11390. + read_random(ses->hs_iv,
  11391. + c->cri_alg == CRYPTO_AES_CBC ?
  11392. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  11393. + /*FALLTHROUGH*/
  11394. + case CRYPTO_ARC4:
  11395. + if (cry) {
  11396. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11397. + return (EINVAL);
  11398. + }
  11399. + cry = 1;
  11400. + break;
  11401. + default:
  11402. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11403. + return (EINVAL);
  11404. + }
  11405. + }
  11406. + if (mac == 0 && cry == 0) {
  11407. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11408. + return (EINVAL);
  11409. + }
  11410. +
  11411. + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
  11412. +
  11413. + return (0);
  11414. +}
  11415. +
  11416. +/*
  11417. + * Deallocate a session.
  11418. + * XXX this routine should run a zero'd mac/encrypt key into context ram.
  11419. + * XXX to blow away any keys already stored there.
  11420. + */
  11421. +static int
  11422. +hifn_freesession(device_t dev, u_int64_t tid)
  11423. +{
  11424. + struct hifn_softc *sc = device_get_softc(dev);
  11425. + int session, error;
  11426. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  11427. + unsigned long l_flags;
  11428. +
  11429. + DPRINTF("%s()\n", __FUNCTION__);
  11430. +
  11431. + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
  11432. + if (sc == NULL) {
  11433. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11434. + return (EINVAL);
  11435. + }
  11436. +
  11437. + HIFN_LOCK(sc);
  11438. + session = HIFN_SESSION(sid);
  11439. + if (session < sc->sc_nsessions) {
  11440. + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
  11441. + error = 0;
  11442. + } else {
  11443. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11444. + error = EINVAL;
  11445. + }
  11446. + HIFN_UNLOCK(sc);
  11447. +
  11448. + return (error);
  11449. +}
  11450. +
  11451. +static int
  11452. +hifn_process(device_t dev, struct cryptop *crp, int hint)
  11453. +{
  11454. + struct hifn_softc *sc = device_get_softc(dev);
  11455. + struct hifn_command *cmd = NULL;
  11456. + int session, err, ivlen;
  11457. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  11458. +
  11459. + DPRINTF("%s()\n", __FUNCTION__);
  11460. +
  11461. + if (crp == NULL || crp->crp_callback == NULL) {
  11462. + hifnstats.hst_invalid++;
  11463. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11464. + return (EINVAL);
  11465. + }
  11466. + session = HIFN_SESSION(crp->crp_sid);
  11467. +
  11468. + if (sc == NULL || session >= sc->sc_nsessions) {
  11469. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11470. + err = EINVAL;
  11471. + goto errout;
  11472. + }
  11473. +
  11474. + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
  11475. + if (cmd == NULL) {
  11476. + hifnstats.hst_nomem++;
  11477. + err = ENOMEM;
  11478. + goto errout;
  11479. + }
  11480. + memset(cmd, 0, sizeof(*cmd));
  11481. +
  11482. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  11483. + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
  11484. + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
  11485. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  11486. + cmd->src_io = (struct uio *)crp->crp_buf;
  11487. + cmd->dst_io = (struct uio *)crp->crp_buf;
  11488. + } else {
  11489. + cmd->src_buf = crp->crp_buf;
  11490. + cmd->dst_buf = crp->crp_buf;
  11491. + }
  11492. +
  11493. + crd1 = crp->crp_desc;
  11494. + if (crd1 == NULL) {
  11495. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11496. + err = EINVAL;
  11497. + goto errout;
  11498. + }
  11499. + crd2 = crd1->crd_next;
  11500. +
  11501. + if (crd2 == NULL) {
  11502. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  11503. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  11504. + crd1->crd_alg == CRYPTO_SHA1 ||
  11505. + crd1->crd_alg == CRYPTO_MD5) {
  11506. + maccrd = crd1;
  11507. + enccrd = NULL;
  11508. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  11509. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  11510. + crd1->crd_alg == CRYPTO_AES_CBC ||
  11511. + crd1->crd_alg == CRYPTO_ARC4) {
  11512. + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
  11513. + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
  11514. + maccrd = NULL;
  11515. + enccrd = crd1;
  11516. + } else {
  11517. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11518. + err = EINVAL;
  11519. + goto errout;
  11520. + }
  11521. + } else {
  11522. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  11523. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  11524. + crd1->crd_alg == CRYPTO_MD5 ||
  11525. + crd1->crd_alg == CRYPTO_SHA1) &&
  11526. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  11527. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  11528. + crd2->crd_alg == CRYPTO_AES_CBC ||
  11529. + crd2->crd_alg == CRYPTO_ARC4) &&
  11530. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  11531. + cmd->base_masks = HIFN_BASE_CMD_DECODE;
  11532. + maccrd = crd1;
  11533. + enccrd = crd2;
  11534. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  11535. + crd1->crd_alg == CRYPTO_ARC4 ||
  11536. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  11537. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  11538. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  11539. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  11540. + crd2->crd_alg == CRYPTO_MD5 ||
  11541. + crd2->crd_alg == CRYPTO_SHA1) &&
  11542. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  11543. + enccrd = crd1;
  11544. + maccrd = crd2;
  11545. + } else {
  11546. + /*
  11547. + * We cannot order the 7751 as requested
  11548. + */
  11549. + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
  11550. + err = EINVAL;
  11551. + goto errout;
  11552. + }
  11553. + }
  11554. +
  11555. + if (enccrd) {
  11556. + cmd->enccrd = enccrd;
  11557. + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
  11558. + switch (enccrd->crd_alg) {
  11559. + case CRYPTO_ARC4:
  11560. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
  11561. + break;
  11562. + case CRYPTO_DES_CBC:
  11563. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
  11564. + HIFN_CRYPT_CMD_MODE_CBC |
  11565. + HIFN_CRYPT_CMD_NEW_IV;
  11566. + break;
  11567. + case CRYPTO_3DES_CBC:
  11568. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
  11569. + HIFN_CRYPT_CMD_MODE_CBC |
  11570. + HIFN_CRYPT_CMD_NEW_IV;
  11571. + break;
  11572. + case CRYPTO_AES_CBC:
  11573. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
  11574. + HIFN_CRYPT_CMD_MODE_CBC |
  11575. + HIFN_CRYPT_CMD_NEW_IV;
  11576. + break;
  11577. + default:
  11578. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11579. + err = EINVAL;
  11580. + goto errout;
  11581. + }
  11582. + if (enccrd->crd_alg != CRYPTO_ARC4) {
  11583. + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
  11584. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  11585. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  11586. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  11587. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  11588. + else
  11589. + bcopy(sc->sc_sessions[session].hs_iv,
  11590. + cmd->iv, ivlen);
  11591. +
  11592. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
  11593. + == 0) {
  11594. + crypto_copyback(crp->crp_flags,
  11595. + crp->crp_buf, enccrd->crd_inject,
  11596. + ivlen, cmd->iv);
  11597. + }
  11598. + } else {
  11599. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  11600. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  11601. + else {
  11602. + crypto_copydata(crp->crp_flags,
  11603. + crp->crp_buf, enccrd->crd_inject,
  11604. + ivlen, cmd->iv);
  11605. + }
  11606. + }
  11607. + }
  11608. +
  11609. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  11610. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  11611. + cmd->ck = enccrd->crd_key;
  11612. + cmd->cklen = enccrd->crd_klen >> 3;
  11613. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  11614. +
  11615. + /*
  11616. + * Need to specify the size for the AES key in the masks.
  11617. + */
  11618. + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
  11619. + HIFN_CRYPT_CMD_ALG_AES) {
  11620. + switch (cmd->cklen) {
  11621. + case 16:
  11622. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
  11623. + break;
  11624. + case 24:
  11625. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
  11626. + break;
  11627. + case 32:
  11628. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
  11629. + break;
  11630. + default:
  11631. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  11632. + err = EINVAL;
  11633. + goto errout;
  11634. + }
  11635. + }
  11636. + }
  11637. +
  11638. + if (maccrd) {
  11639. + cmd->maccrd = maccrd;
  11640. + cmd->base_masks |= HIFN_BASE_CMD_MAC;
  11641. +
  11642. + switch (maccrd->crd_alg) {
  11643. + case CRYPTO_MD5:
  11644. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  11645. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  11646. + HIFN_MAC_CMD_POS_IPSEC;
  11647. + break;
  11648. + case CRYPTO_MD5_HMAC:
  11649. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  11650. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  11651. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  11652. + break;
  11653. + case CRYPTO_SHA1:
  11654. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  11655. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  11656. + HIFN_MAC_CMD_POS_IPSEC;
  11657. + break;
  11658. + case CRYPTO_SHA1_HMAC:
  11659. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  11660. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  11661. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  11662. + break;
  11663. + }
  11664. +
  11665. + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
  11666. + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  11667. + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
  11668. + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
  11669. + bzero(cmd->mac + (maccrd->crd_klen >> 3),
  11670. + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
  11671. + }
  11672. + }
  11673. +
  11674. + cmd->crp = crp;
  11675. + cmd->session_num = session;
  11676. + cmd->softc = sc;
  11677. +
  11678. + err = hifn_crypto(sc, cmd, crp, hint);
  11679. + if (!err) {
  11680. + return 0;
  11681. + } else if (err == ERESTART) {
  11682. + /*
  11683. + * There weren't enough resources to dispatch the request
  11684. + * to the part. Notify the caller so they'll requeue this
  11685. + * request and resubmit it again soon.
  11686. + */
  11687. +#ifdef HIFN_DEBUG
  11688. + if (hifn_debug)
  11689. + device_printf(sc->sc_dev, "requeue request\n");
  11690. +#endif
  11691. + kfree(cmd);
  11692. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  11693. + return (err);
  11694. + }
  11695. +
  11696. +errout:
  11697. + if (cmd != NULL)
  11698. + kfree(cmd);
  11699. + if (err == EINVAL)
  11700. + hifnstats.hst_invalid++;
  11701. + else
  11702. + hifnstats.hst_nomem++;
  11703. + crp->crp_etype = err;
  11704. + crypto_done(crp);
  11705. + return (err);
  11706. +}
  11707. +
  11708. +static void
  11709. +hifn_abort(struct hifn_softc *sc)
  11710. +{
  11711. + struct hifn_dma *dma = sc->sc_dma;
  11712. + struct hifn_command *cmd;
  11713. + struct cryptop *crp;
  11714. + int i, u;
  11715. +
  11716. + DPRINTF("%s()\n", __FUNCTION__);
  11717. +
  11718. + i = dma->resk; u = dma->resu;
  11719. + while (u != 0) {
  11720. + cmd = dma->hifn_commands[i];
  11721. + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
  11722. + dma->hifn_commands[i] = NULL;
  11723. + crp = cmd->crp;
  11724. +
  11725. + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
  11726. + /* Salvage what we can. */
  11727. + u_int8_t *macbuf;
  11728. +
  11729. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  11730. + macbuf = dma->result_bufs[i];
  11731. + macbuf += 12;
  11732. + } else
  11733. + macbuf = NULL;
  11734. + hifnstats.hst_opackets++;
  11735. + hifn_callback(sc, cmd, macbuf);
  11736. + } else {
  11737. +#if 0
  11738. + if (cmd->src_map == cmd->dst_map) {
  11739. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11740. + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  11741. + } else {
  11742. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11743. + BUS_DMASYNC_POSTWRITE);
  11744. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  11745. + BUS_DMASYNC_POSTREAD);
  11746. + }
  11747. +#endif
  11748. +
  11749. + if (cmd->src_skb != cmd->dst_skb) {
  11750. +#ifdef NOTYET
  11751. + m_freem(cmd->src_m);
  11752. + crp->crp_buf = (caddr_t)cmd->dst_m;
  11753. +#else
  11754. + device_printf(sc->sc_dev,
  11755. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  11756. + __FILE__, __LINE__);
  11757. +#endif
  11758. + }
  11759. +
  11760. + /* non-shared buffers cannot be restarted */
  11761. + if (cmd->src_map != cmd->dst_map) {
  11762. + /*
  11763. + * XXX should be EAGAIN, delayed until
  11764. + * after the reset.
  11765. + */
  11766. + crp->crp_etype = ENOMEM;
  11767. + pci_unmap_buf(sc, &cmd->dst);
  11768. + } else
  11769. + crp->crp_etype = ENOMEM;
  11770. +
  11771. + pci_unmap_buf(sc, &cmd->src);
  11772. +
  11773. + kfree(cmd);
  11774. + if (crp->crp_etype != EAGAIN)
  11775. + crypto_done(crp);
  11776. + }
  11777. +
  11778. + if (++i == HIFN_D_RES_RSIZE)
  11779. + i = 0;
  11780. + u--;
  11781. + }
  11782. + dma->resk = i; dma->resu = u;
  11783. +
  11784. + hifn_reset_board(sc, 1);
  11785. + hifn_init_dma(sc);
  11786. + hifn_init_pci_registers(sc);
  11787. +}
  11788. +
  11789. +static void
  11790. +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
  11791. +{
  11792. + struct hifn_dma *dma = sc->sc_dma;
  11793. + struct cryptop *crp = cmd->crp;
  11794. + struct cryptodesc *crd;
  11795. + int i, u, ivlen;
  11796. +
  11797. + DPRINTF("%s()\n", __FUNCTION__);
  11798. +
  11799. +#if 0
  11800. + if (cmd->src_map == cmd->dst_map) {
  11801. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11802. + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  11803. + } else {
  11804. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  11805. + BUS_DMASYNC_POSTWRITE);
  11806. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  11807. + BUS_DMASYNC_POSTREAD);
  11808. + }
  11809. +#endif
  11810. +
  11811. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  11812. + if (cmd->src_skb != cmd->dst_skb) {
  11813. +#ifdef NOTYET
  11814. + crp->crp_buf = (caddr_t)cmd->dst_m;
  11815. + totlen = cmd->src_mapsize;
  11816. + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
  11817. + if (totlen < m->m_len) {
  11818. + m->m_len = totlen;
  11819. + totlen = 0;
  11820. + } else
  11821. + totlen -= m->m_len;
  11822. + }
  11823. + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
  11824. + m_freem(cmd->src_m);
  11825. +#else
  11826. + device_printf(sc->sc_dev,
  11827. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  11828. + __FILE__, __LINE__);
  11829. +#endif
  11830. + }
  11831. + }
  11832. +
  11833. + if (cmd->sloplen != 0) {
  11834. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  11835. + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
  11836. + (caddr_t)&dma->slop[cmd->slopidx]);
  11837. + }
  11838. +
  11839. + i = dma->dstk; u = dma->dstu;
  11840. + while (u != 0) {
  11841. + if (i == HIFN_D_DST_RSIZE)
  11842. + i = 0;
  11843. +#if 0
  11844. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  11845. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  11846. +#endif
  11847. + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
  11848. +#if 0
  11849. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  11850. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  11851. +#endif
  11852. + break;
  11853. + }
  11854. + i++, u--;
  11855. + }
  11856. + dma->dstk = i; dma->dstu = u;
  11857. +
  11858. + hifnstats.hst_obytes += cmd->dst_mapsize;
  11859. +
  11860. + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
  11861. + HIFN_BASE_CMD_CRYPT) {
  11862. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  11863. + if (crd->crd_alg != CRYPTO_DES_CBC &&
  11864. + crd->crd_alg != CRYPTO_3DES_CBC &&
  11865. + crd->crd_alg != CRYPTO_AES_CBC)
  11866. + continue;
  11867. + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
  11868. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  11869. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  11870. + crd->crd_skip + crd->crd_len - ivlen, ivlen,
  11871. + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
  11872. + break;
  11873. + }
  11874. + }
  11875. +
  11876. + if (macbuf != NULL) {
  11877. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  11878. + int len;
  11879. +
  11880. + if (crd->crd_alg != CRYPTO_MD5 &&
  11881. + crd->crd_alg != CRYPTO_SHA1 &&
  11882. + crd->crd_alg != CRYPTO_MD5_HMAC &&
  11883. + crd->crd_alg != CRYPTO_SHA1_HMAC) {
  11884. + continue;
  11885. + }
  11886. + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
  11887. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  11888. + crd->crd_inject, len, macbuf);
  11889. + break;
  11890. + }
  11891. + }
  11892. +
  11893. + if (cmd->src_map != cmd->dst_map)
  11894. + pci_unmap_buf(sc, &cmd->dst);
  11895. + pci_unmap_buf(sc, &cmd->src);
  11896. + kfree(cmd);
  11897. + crypto_done(crp);
  11898. +}
  11899. +
  11900. +/*
  11901. + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
  11902. + * and Group 1 registers; avoid conditions that could create
  11903. + * burst writes by doing a read in between the writes.
  11904. + *
  11905. + * NB: The read we interpose is always to the same register;
  11906. + * we do this because reading from an arbitrary (e.g. last)
  11907. + * register may not always work.
  11908. + */
  11909. +static void
  11910. +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  11911. +{
  11912. + if (sc->sc_flags & HIFN_IS_7811) {
  11913. + if (sc->sc_bar0_lastreg == reg - 4)
  11914. + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
  11915. + sc->sc_bar0_lastreg = reg;
  11916. + }
  11917. + writel(val, sc->sc_bar0 + reg);
  11918. +}
  11919. +
  11920. +static void
  11921. +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  11922. +{
  11923. + if (sc->sc_flags & HIFN_IS_7811) {
  11924. + if (sc->sc_bar1_lastreg == reg - 4)
  11925. + readl(sc->sc_bar1 + HIFN_1_REVID);
  11926. + sc->sc_bar1_lastreg = reg;
  11927. + }
  11928. + writel(val, sc->sc_bar1 + reg);
  11929. +}
  11930. +
  11931. +
  11932. +static struct pci_device_id hifn_pci_tbl[] = {
  11933. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
  11934. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11935. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
  11936. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11937. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
  11938. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11939. + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
  11940. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11941. + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
  11942. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11943. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
  11944. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11945. + /*
  11946. + * Other vendors share this PCI ID as well, such as
  11947. + * http://www.powercrypt.com, and obviously they also
  11948. + * use the same key.
  11949. + */
  11950. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
  11951. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  11952. + { 0, 0, 0, 0, 0, 0, }
  11953. +};
  11954. +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
  11955. +
  11956. +static struct pci_driver hifn_driver = {
  11957. + .name = "hifn",
  11958. + .id_table = hifn_pci_tbl,
  11959. + .probe = hifn_probe,
  11960. + .remove = hifn_remove,
  11961. + /* add PM stuff here one day */
  11962. +};
  11963. +
  11964. +static int __init hifn_init (void)
  11965. +{
  11966. + struct hifn_softc *sc = NULL;
  11967. + int rc;
  11968. +
  11969. + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
  11970. +
  11971. + rc = pci_register_driver(&hifn_driver);
  11972. + pci_register_driver_compat(&hifn_driver, rc);
  11973. +
  11974. + return rc;
  11975. +}
  11976. +
  11977. +static void __exit hifn_exit (void)
  11978. +{
  11979. + pci_unregister_driver(&hifn_driver);
  11980. +}
  11981. +
  11982. +module_init(hifn_init);
  11983. +module_exit(hifn_exit);
  11984. +
  11985. +MODULE_LICENSE("BSD");
  11986. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  11987. +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
  11988. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.29.1/crypto/ocf/hifn/hifn7751reg.h
  11989. --- linux-2.6.29.1.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
  11990. +++ linux-2.6.29.1/crypto/ocf/hifn/hifn7751reg.h 2009-04-20 20:01:21.488556145 +0200
  11991. @@ -0,0 +1,540 @@
  11992. +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
  11993. +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
  11994. +
  11995. +/*-
  11996. + * Invertex AEON / Hifn 7751 driver
  11997. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  11998. + * Copyright (c) 1999 Theo de Raadt
  11999. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  12000. + * http://www.netsec.net
  12001. + *
  12002. + * Please send any comments, feedback, bug-fixes, or feature requests to
  12003. + * software@invertex.com.
  12004. + *
  12005. + * Redistribution and use in source and binary forms, with or without
  12006. + * modification, are permitted provided that the following conditions
  12007. + * are met:
  12008. + *
  12009. + * 1. Redistributions of source code must retain the above copyright
  12010. + * notice, this list of conditions and the following disclaimer.
  12011. + * 2. Redistributions in binary form must reproduce the above copyright
  12012. + * notice, this list of conditions and the following disclaimer in the
  12013. + * documentation and/or other materials provided with the distribution.
  12014. + * 3. The name of the author may not be used to endorse or promote products
  12015. + * derived from this software without specific prior written permission.
  12016. + *
  12017. + *
  12018. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12019. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12020. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12021. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12022. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12023. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12024. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12025. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12026. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12027. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12028. + *
  12029. + * Effort sponsored in part by the Defense Advanced Research Projects
  12030. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  12031. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  12032. + *
  12033. + */
  12034. +#ifndef __HIFN_H__
  12035. +#define __HIFN_H__
  12036. +
  12037. +/*
  12038. + * Some PCI configuration space offset defines. The names were made
  12039. + * identical to the names used by the Linux kernel.
  12040. + */
  12041. +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
  12042. +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
  12043. +#define HIFN_TRDY_TIMEOUT 0x40
  12044. +#define HIFN_RETRY_TIMEOUT 0x41
  12045. +
  12046. +/*
  12047. + * PCI vendor and device identifiers
  12048. + * (the names are preserved from their OpenBSD source).
  12049. + */
  12050. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  12051. +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
  12052. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  12053. +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
  12054. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  12055. +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
  12056. +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
  12057. +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
  12058. +
  12059. +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
  12060. +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
  12061. +
  12062. +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
  12063. +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
  12064. +
  12065. +/*
  12066. + * The values below should multiple of 4 -- and be large enough to handle
  12067. + * any command the driver implements.
  12068. + *
  12069. + * MAX_COMMAND = base command + mac command + encrypt command +
  12070. + * mac-key + rc4-key
  12071. + * MAX_RESULT = base result + mac result + mac + encrypt result
  12072. + *
  12073. + *
  12074. + */
  12075. +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
  12076. +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
  12077. +
  12078. +/*
  12079. + * hifn_desc_t
  12080. + *
  12081. + * Holds an individual descriptor for any of the rings.
  12082. + */
  12083. +typedef struct hifn_desc {
  12084. + volatile u_int32_t l; /* length and status bits */
  12085. + volatile u_int32_t p;
  12086. +} hifn_desc_t;
  12087. +
  12088. +/*
  12089. + * Masks for the "length" field of struct hifn_desc.
  12090. + */
  12091. +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
  12092. +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
  12093. +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
  12094. +#define HIFN_D_OVER 0x08000000 /* overflow */
  12095. +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
  12096. +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
  12097. +#define HIFN_D_VALID 0x80000000 /* valid bit */
  12098. +
  12099. +
  12100. +/*
  12101. + * Processing Unit Registers (offset from BASEREG0)
  12102. + */
  12103. +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
  12104. +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
  12105. +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
  12106. +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
  12107. +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
  12108. +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
  12109. +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
  12110. +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
  12111. +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
  12112. +#define HIFN_0_MUTE1 0x80
  12113. +#define HIFN_0_MUTE2 0x90
  12114. +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
  12115. +
  12116. +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
  12117. +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
  12118. +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
  12119. +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
  12120. +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
  12121. +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
  12122. +
  12123. +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
  12124. +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
  12125. +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
  12126. +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  12127. +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  12128. +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
  12129. +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
  12130. +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
  12131. +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
  12132. +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
  12133. +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
  12134. +
  12135. +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
  12136. +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
  12137. +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
  12138. +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
  12139. +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
  12140. +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
  12141. +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
  12142. +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
  12143. +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
  12144. +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
  12145. +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
  12146. +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
  12147. +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
  12148. +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
  12149. +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
  12150. +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
  12151. +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
  12152. +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
  12153. +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
  12154. +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
  12155. +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
  12156. +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
  12157. +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
  12158. +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
  12159. +
  12160. +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
  12161. +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
  12162. +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
  12163. +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  12164. +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  12165. +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
  12166. +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
  12167. +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
  12168. +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
  12169. +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
  12170. +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
  12171. +
  12172. +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
  12173. +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
  12174. +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
  12175. +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  12176. +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  12177. +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
  12178. +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
  12179. +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
  12180. +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
  12181. +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
  12182. +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
  12183. +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
  12184. +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
  12185. +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
  12186. +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
  12187. +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
  12188. +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
  12189. +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
  12190. +
  12191. +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
  12192. +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
  12193. +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
  12194. +
  12195. +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
  12196. +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
  12197. +
  12198. +/*
  12199. + * DMA Interface Registers (offset from BASEREG1)
  12200. + */
  12201. +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
  12202. +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
  12203. +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
  12204. +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
  12205. +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
  12206. +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
  12207. +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
  12208. +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
  12209. +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
  12210. +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
  12211. +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
  12212. +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
  12213. +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
  12214. +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
  12215. +#define HIFN_1_REVID 0x98 /* Revision ID */
  12216. +
  12217. +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
  12218. +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
  12219. +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
  12220. +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
  12221. +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
  12222. +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
  12223. +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
  12224. +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
  12225. +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
  12226. +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
  12227. +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
  12228. +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
  12229. +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
  12230. +
  12231. +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
  12232. +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
  12233. +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
  12234. +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
  12235. +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
  12236. +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
  12237. +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
  12238. +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
  12239. +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
  12240. +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
  12241. +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
  12242. +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
  12243. +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
  12244. +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
  12245. +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  12246. +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
  12247. +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
  12248. +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
  12249. +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
  12250. +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
  12251. +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
  12252. +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
  12253. +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
  12254. +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  12255. +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
  12256. +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
  12257. +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
  12258. +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
  12259. +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
  12260. +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
  12261. +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
  12262. +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
  12263. +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
  12264. +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  12265. +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
  12266. +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
  12267. +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
  12268. +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
  12269. +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
  12270. +
  12271. +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
  12272. +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
  12273. +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
  12274. +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
  12275. +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
  12276. +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
  12277. +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  12278. +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
  12279. +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
  12280. +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
  12281. +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
  12282. +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  12283. +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
  12284. +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
  12285. +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
  12286. +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
  12287. +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
  12288. +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  12289. +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
  12290. +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
  12291. +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
  12292. +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
  12293. +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
  12294. +
  12295. +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
  12296. +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
  12297. +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
  12298. +#define HIFN_DMACNFG_UNLOCK 0x00000800
  12299. +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
  12300. +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
  12301. +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
  12302. +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
  12303. +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
  12304. +
  12305. +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
  12306. +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
  12307. +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
  12308. +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
  12309. +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
  12310. +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
  12311. +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
  12312. +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
  12313. +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
  12314. +
  12315. +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
  12316. +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
  12317. +
  12318. +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
  12319. +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
  12320. +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
  12321. +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
  12322. +
  12323. +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
  12324. +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
  12325. +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
  12326. +
  12327. +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
  12328. +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
  12329. +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
  12330. +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
  12331. +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
  12332. +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
  12333. +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
  12334. +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
  12335. +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
  12336. +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
  12337. +
  12338. +/* Public key reset register (HIFN_1_PUB_RESET) */
  12339. +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
  12340. +
  12341. +/* Public operation register (HIFN_1_PUB_OP) */
  12342. +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
  12343. +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
  12344. +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
  12345. +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
  12346. +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
  12347. +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
  12348. +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
  12349. +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
  12350. +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
  12351. +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
  12352. +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
  12353. +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
  12354. +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
  12355. +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
  12356. +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
  12357. +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
  12358. +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
  12359. +
  12360. +/* Public operand length register (HIFN_1_PUB_OPLEN) */
  12361. +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
  12362. +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
  12363. +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
  12364. +
  12365. +/* Public status register (HIFN_1_PUB_STATUS) */
  12366. +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
  12367. +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
  12368. +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
  12369. +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
  12370. +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
  12371. +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
  12372. +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
  12373. +
  12374. +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
  12375. +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
  12376. +
  12377. +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
  12378. +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
  12379. +
  12380. +/*
  12381. + * Register offsets in register set 1
  12382. + */
  12383. +
  12384. +#define HIFN_UNLOCK_SECRET1 0xf4
  12385. +#define HIFN_UNLOCK_SECRET2 0xfc
  12386. +
  12387. +/*
  12388. + * PLL config register
  12389. + *
  12390. + * This register is present only on 7954/7955/7956 parts. It must be
  12391. + * programmed according to the bus interface method used by the h/w.
  12392. + * Note that the parts require a stable clock. Since the PCI clock
  12393. + * may vary the reference clock must usually be used. To avoid
  12394. + * overclocking the core logic, setup must be done carefully, refer
  12395. + * to the driver for details. The exact multiplier required varies
  12396. + * by part and system configuration; refer to the Hifn documentation.
  12397. + */
  12398. +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
  12399. +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
  12400. +/* bit 2 reserved */
  12401. +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
  12402. +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
  12403. +/* bits 5-9 reserved */
  12404. +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
  12405. +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
  12406. +#define HIFN_PLL_ND_SHIFT 11
  12407. +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
  12408. +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
  12409. +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
  12410. +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
  12411. +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
  12412. +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
  12413. +/* bits 14-15 reserved */
  12414. +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
  12415. +/* bits 17-31 reserved */
  12416. +
  12417. +/*
  12418. + * Board configuration specifies only these bits.
  12419. + */
  12420. +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
  12421. +
  12422. +/*
  12423. + * Public Key Engine Mode Register
  12424. + */
  12425. +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
  12426. +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
  12427. +
  12428. +
  12429. +/*********************************************************************
  12430. + * Structs for board commands
  12431. + *
  12432. + *********************************************************************/
  12433. +
  12434. +/*
  12435. + * Structure to help build up the command data structure.
  12436. + */
  12437. +typedef struct hifn_base_command {
  12438. + volatile u_int16_t masks;
  12439. + volatile u_int16_t session_num;
  12440. + volatile u_int16_t total_source_count;
  12441. + volatile u_int16_t total_dest_count;
  12442. +} hifn_base_command_t;
  12443. +
  12444. +#define HIFN_BASE_CMD_MAC 0x0400
  12445. +#define HIFN_BASE_CMD_CRYPT 0x0800
  12446. +#define HIFN_BASE_CMD_DECODE 0x2000
  12447. +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
  12448. +#define HIFN_BASE_CMD_SRCLEN_S 14
  12449. +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
  12450. +#define HIFN_BASE_CMD_DSTLEN_S 12
  12451. +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
  12452. +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
  12453. +
  12454. +/*
  12455. + * Structure to help build up the command data structure.
  12456. + */
  12457. +typedef struct hifn_crypt_command {
  12458. + volatile u_int16_t masks;
  12459. + volatile u_int16_t header_skip;
  12460. + volatile u_int16_t source_count;
  12461. + volatile u_int16_t reserved;
  12462. +} hifn_crypt_command_t;
  12463. +
  12464. +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
  12465. +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
  12466. +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
  12467. +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
  12468. +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
  12469. +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
  12470. +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
  12471. +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
  12472. +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
  12473. +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
  12474. +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
  12475. +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
  12476. +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
  12477. +
  12478. +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
  12479. +#define HIFN_CRYPT_CMD_SRCLEN_S 14
  12480. +
  12481. +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
  12482. +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
  12483. +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
  12484. +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
  12485. +
  12486. +/*
  12487. + * Structure to help build up the command data structure.
  12488. + */
  12489. +typedef struct hifn_mac_command {
  12490. + volatile u_int16_t masks;
  12491. + volatile u_int16_t header_skip;
  12492. + volatile u_int16_t source_count;
  12493. + volatile u_int16_t reserved;
  12494. +} hifn_mac_command_t;
  12495. +
  12496. +#define HIFN_MAC_CMD_ALG_MASK 0x0001
  12497. +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
  12498. +#define HIFN_MAC_CMD_ALG_MD5 0x0001
  12499. +#define HIFN_MAC_CMD_MODE_MASK 0x000c
  12500. +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
  12501. +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
  12502. +#define HIFN_MAC_CMD_MODE_HASH 0x0008
  12503. +#define HIFN_MAC_CMD_MODE_FULL 0x0004
  12504. +#define HIFN_MAC_CMD_TRUNC 0x0010
  12505. +#define HIFN_MAC_CMD_RESULT 0x0020
  12506. +#define HIFN_MAC_CMD_APPEND 0x0040
  12507. +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
  12508. +#define HIFN_MAC_CMD_SRCLEN_S 14
  12509. +
  12510. +/*
  12511. + * MAC POS IPsec initiates authentication after encryption on encodes
  12512. + * and before decryption on decodes.
  12513. + */
  12514. +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
  12515. +#define HIFN_MAC_CMD_NEW_KEY 0x0800
  12516. +
  12517. +/*
  12518. + * The poll frequency and poll scalar defines are unshifted values used
  12519. + * to set fields in the DMA Configuration Register.
  12520. + */
  12521. +#ifndef HIFN_POLL_FREQUENCY
  12522. +#define HIFN_POLL_FREQUENCY 0x1
  12523. +#endif
  12524. +
  12525. +#ifndef HIFN_POLL_SCALAR
  12526. +#define HIFN_POLL_SCALAR 0x0
  12527. +#endif
  12528. +
  12529. +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
  12530. +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
  12531. +#endif /* __HIFN_H__ */
  12532. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.29.1/crypto/ocf/hifn/hifn7751var.h
  12533. --- linux-2.6.29.1.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
  12534. +++ linux-2.6.29.1/crypto/ocf/hifn/hifn7751var.h 2009-04-20 20:01:21.488556145 +0200
  12535. @@ -0,0 +1,369 @@
  12536. +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
  12537. +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
  12538. +
  12539. +/*-
  12540. + * Invertex AEON / Hifn 7751 driver
  12541. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  12542. + * Copyright (c) 1999 Theo de Raadt
  12543. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  12544. + * http://www.netsec.net
  12545. + *
  12546. + * Please send any comments, feedback, bug-fixes, or feature requests to
  12547. + * software@invertex.com.
  12548. + *
  12549. + * Redistribution and use in source and binary forms, with or without
  12550. + * modification, are permitted provided that the following conditions
  12551. + * are met:
  12552. + *
  12553. + * 1. Redistributions of source code must retain the above copyright
  12554. + * notice, this list of conditions and the following disclaimer.
  12555. + * 2. Redistributions in binary form must reproduce the above copyright
  12556. + * notice, this list of conditions and the following disclaimer in the
  12557. + * documentation and/or other materials provided with the distribution.
  12558. + * 3. The name of the author may not be used to endorse or promote products
  12559. + * derived from this software without specific prior written permission.
  12560. + *
  12561. + *
  12562. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12563. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12564. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12565. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12566. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12567. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12568. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12569. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12570. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12571. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12572. + *
  12573. + * Effort sponsored in part by the Defense Advanced Research Projects
  12574. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  12575. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  12576. + *
  12577. + */
  12578. +
  12579. +#ifndef __HIFN7751VAR_H__
  12580. +#define __HIFN7751VAR_H__
  12581. +
  12582. +#ifdef __KERNEL__
  12583. +
  12584. +/*
  12585. + * Some configurable values for the driver. By default command+result
  12586. + * descriptor rings are the same size. The src+dst descriptor rings
  12587. + * are sized at 3.5x the number of potential commands. Slower parts
  12588. + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
  12589. + * src+cmd/result descriptors. It's not clear that increasing the size
  12590. + * of the descriptor rings helps performance significantly as other
  12591. + * factors tend to come into play (e.g. copying misaligned packets).
  12592. + */
  12593. +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
  12594. +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
  12595. +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
  12596. +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
  12597. +
  12598. +/*
  12599. + * Length values for cryptography
  12600. + */
  12601. +#define HIFN_DES_KEY_LENGTH 8
  12602. +#define HIFN_3DES_KEY_LENGTH 24
  12603. +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
  12604. +#define HIFN_IV_LENGTH 8
  12605. +#define HIFN_AES_IV_LENGTH 16
  12606. +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
  12607. +
  12608. +/*
  12609. + * Length values for authentication
  12610. + */
  12611. +#define HIFN_MAC_KEY_LENGTH 64
  12612. +#define HIFN_MD5_LENGTH 16
  12613. +#define HIFN_SHA1_LENGTH 20
  12614. +#define HIFN_MAC_TRUNC_LENGTH 12
  12615. +
  12616. +#define MAX_SCATTER 64
  12617. +
  12618. +/*
  12619. + * Data structure to hold all 4 rings and any other ring related data.
  12620. + */
  12621. +struct hifn_dma {
  12622. + /*
  12623. + * Descriptor rings. We add +1 to the size to accomidate the
  12624. + * jump descriptor.
  12625. + */
  12626. + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
  12627. + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
  12628. + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
  12629. + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
  12630. +
  12631. + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
  12632. +
  12633. + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
  12634. + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
  12635. + u_int32_t slop[HIFN_D_CMD_RSIZE];
  12636. +
  12637. + u_int64_t test_src, test_dst;
  12638. +
  12639. + /*
  12640. + * Our current positions for insertion and removal from the desriptor
  12641. + * rings.
  12642. + */
  12643. + int cmdi, srci, dsti, resi;
  12644. + volatile int cmdu, srcu, dstu, resu;
  12645. + int cmdk, srck, dstk, resk;
  12646. +};
  12647. +
  12648. +struct hifn_session {
  12649. + int hs_used;
  12650. + int hs_mlen;
  12651. + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
  12652. +};
  12653. +
  12654. +#define HIFN_RING_SYNC(sc, r, i, f) \
  12655. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  12656. +
  12657. +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
  12658. +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
  12659. +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
  12660. +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
  12661. +
  12662. +#define HIFN_CMD_SYNC(sc, i, f) \
  12663. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  12664. +
  12665. +#define HIFN_RES_SYNC(sc, i, f) \
  12666. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  12667. +
  12668. +typedef int bus_size_t;
  12669. +
  12670. +/*
  12671. + * Holds data specific to a single HIFN board.
  12672. + */
  12673. +struct hifn_softc {
  12674. + softc_device_decl sc_dev;
  12675. +
  12676. + struct pci_dev *sc_pcidev; /* PCI device pointer */
  12677. + spinlock_t sc_mtx; /* per-instance lock */
  12678. +
  12679. + int sc_num; /* for multiple devs */
  12680. +
  12681. + ocf_iomem_t sc_bar0;
  12682. + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
  12683. + ocf_iomem_t sc_bar1;
  12684. + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
  12685. +
  12686. + int sc_irq;
  12687. +
  12688. + u_int32_t sc_dmaier;
  12689. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  12690. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  12691. +
  12692. + struct hifn_dma *sc_dma;
  12693. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  12694. +
  12695. + int sc_dmansegs;
  12696. + int32_t sc_cid;
  12697. + int sc_maxses;
  12698. + int sc_nsessions;
  12699. + struct hifn_session *sc_sessions;
  12700. + int sc_ramsize;
  12701. + int sc_flags;
  12702. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  12703. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  12704. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  12705. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  12706. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  12707. +
  12708. + struct timer_list sc_tickto; /* for managing DMA */
  12709. +
  12710. + int sc_rngfirst;
  12711. + int sc_rnghz; /* RNG polling frequency */
  12712. +
  12713. + int sc_c_busy; /* command ring busy */
  12714. + int sc_s_busy; /* source data ring busy */
  12715. + int sc_d_busy; /* destination data ring busy */
  12716. + int sc_r_busy; /* result ring busy */
  12717. + int sc_active; /* for initial countdown */
  12718. + int sc_needwakeup; /* ops q'd wating on resources */
  12719. + int sc_curbatch; /* # ops submitted w/o int */
  12720. + int sc_suspended;
  12721. +#ifdef HIFN_VULCANDEV
  12722. + struct cdev *sc_pkdev;
  12723. +#endif
  12724. +};
  12725. +
  12726. +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  12727. +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  12728. +
  12729. +/*
  12730. + * hifn_command_t
  12731. + *
  12732. + * This is the control structure used to pass commands to hifn_encrypt().
  12733. + *
  12734. + * flags
  12735. + * -----
  12736. + * Flags is the bitwise "or" values for command configuration. A single
  12737. + * encrypt direction needs to be set:
  12738. + *
  12739. + * HIFN_ENCODE or HIFN_DECODE
  12740. + *
  12741. + * To use cryptography, a single crypto algorithm must be included:
  12742. + *
  12743. + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
  12744. + *
  12745. + * To use authentication is used, a single MAC algorithm must be included:
  12746. + *
  12747. + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
  12748. + *
  12749. + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
  12750. + * If the value below is set, hash values are truncated or assumed
  12751. + * truncated to 12 bytes:
  12752. + *
  12753. + * HIFN_MAC_TRUNC
  12754. + *
  12755. + * Keys for encryption and authentication can be sent as part of a command,
  12756. + * or the last key value used with a particular session can be retrieved
  12757. + * and used again if either of these flags are not specified.
  12758. + *
  12759. + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
  12760. + *
  12761. + * session_num
  12762. + * -----------
  12763. + * A number between 0 and 2048 (for DRAM models) or a number between
  12764. + * 0 and 768 (for SRAM models). Those who don't want to use session
  12765. + * numbers should leave value at zero and send a new crypt key and/or
  12766. + * new MAC key on every command. If you use session numbers and
  12767. + * don't send a key with a command, the last key sent for that same
  12768. + * session number will be used.
  12769. + *
  12770. + * Warning: Using session numbers and multiboard at the same time
  12771. + * is currently broken.
  12772. + *
  12773. + * mbuf
  12774. + * ----
  12775. + * Either fill in the mbuf pointer and npa=0 or
  12776. + * fill packp[] and packl[] and set npa to > 0
  12777. + *
  12778. + * mac_header_skip
  12779. + * ---------------
  12780. + * The number of bytes of the source_buf that are skipped over before
  12781. + * authentication begins. This must be a number between 0 and 2^16-1
  12782. + * and can be used by IPsec implementers to skip over IP headers.
  12783. + * *** Value ignored if authentication not used ***
  12784. + *
  12785. + * crypt_header_skip
  12786. + * -----------------
  12787. + * The number of bytes of the source_buf that are skipped over before
  12788. + * the cryptographic operation begins. This must be a number between 0
  12789. + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
  12790. + * than the auth_header_skip (to skip over the ESP header).
  12791. + * *** Value ignored if cryptography not used ***
  12792. + *
  12793. + */
  12794. +struct hifn_operand {
  12795. + union {
  12796. + struct sk_buff *skb;
  12797. + struct uio *io;
  12798. + unsigned char *buf;
  12799. + } u;
  12800. + void *map;
  12801. + bus_size_t mapsize;
  12802. + int nsegs;
  12803. + struct {
  12804. + dma_addr_t ds_addr;
  12805. + int ds_len;
  12806. + } segs[MAX_SCATTER];
  12807. +};
  12808. +
  12809. +struct hifn_command {
  12810. + u_int16_t session_num;
  12811. + u_int16_t base_masks, cry_masks, mac_masks;
  12812. + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
  12813. + int cklen;
  12814. + int sloplen, slopidx;
  12815. +
  12816. + struct hifn_operand src;
  12817. + struct hifn_operand dst;
  12818. +
  12819. + struct hifn_softc *softc;
  12820. + struct cryptop *crp;
  12821. + struct cryptodesc *enccrd, *maccrd;
  12822. +};
  12823. +
  12824. +#define src_skb src.u.skb
  12825. +#define src_io src.u.io
  12826. +#define src_map src.map
  12827. +#define src_mapsize src.mapsize
  12828. +#define src_segs src.segs
  12829. +#define src_nsegs src.nsegs
  12830. +#define src_buf src.u.buf
  12831. +
  12832. +#define dst_skb dst.u.skb
  12833. +#define dst_io dst.u.io
  12834. +#define dst_map dst.map
  12835. +#define dst_mapsize dst.mapsize
  12836. +#define dst_segs dst.segs
  12837. +#define dst_nsegs dst.nsegs
  12838. +#define dst_buf dst.u.buf
  12839. +
  12840. +/*
  12841. + * Return values for hifn_crypto()
  12842. + */
  12843. +#define HIFN_CRYPTO_SUCCESS 0
  12844. +#define HIFN_CRYPTO_BAD_INPUT (-1)
  12845. +#define HIFN_CRYPTO_RINGS_FULL (-2)
  12846. +
  12847. +/**************************************************************************
  12848. + *
  12849. + * Function: hifn_crypto
  12850. + *
  12851. + * Purpose: Called by external drivers to begin an encryption on the
  12852. + * HIFN board.
  12853. + *
  12854. + * Blocking/Non-blocking Issues
  12855. + * ============================
  12856. + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
  12857. + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
  12858. + * room in any of the rings for the request to proceed.
  12859. + *
  12860. + * Return Values
  12861. + * =============
  12862. + * 0 for success, negative values on error
  12863. + *
  12864. + * Defines for negative error codes are:
  12865. + *
  12866. + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
  12867. + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
  12868. + * behaviour was requested.
  12869. + *
  12870. + *************************************************************************/
  12871. +
  12872. +/*
  12873. + * Convert back and forth from 'sid' to 'card' and 'session'
  12874. + */
  12875. +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
  12876. +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
  12877. +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
  12878. +
  12879. +#endif /* _KERNEL */
  12880. +
  12881. +struct hifn_stats {
  12882. + u_int64_t hst_ibytes;
  12883. + u_int64_t hst_obytes;
  12884. + u_int32_t hst_ipackets;
  12885. + u_int32_t hst_opackets;
  12886. + u_int32_t hst_invalid;
  12887. + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
  12888. + u_int32_t hst_abort;
  12889. + u_int32_t hst_noirq; /* IRQ for no reason */
  12890. + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
  12891. + u_int32_t hst_maxbatch; /* max ops submitted together */
  12892. + u_int32_t hst_unaligned; /* unaligned src caused copy */
  12893. + /*
  12894. + * The following divides hst_nomem into more specific buckets.
  12895. + */
  12896. + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
  12897. + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
  12898. + u_int32_t hst_nomem_mbuf; /* MGET* failed */
  12899. + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
  12900. + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
  12901. + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
  12902. +};
  12903. +
  12904. +#endif /* __HIFN7751VAR_H__ */
  12905. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.29.1/crypto/ocf/hifn/hifnHIPP.c
  12906. --- linux-2.6.29.1.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
  12907. +++ linux-2.6.29.1/crypto/ocf/hifn/hifnHIPP.c 2009-04-20 20:01:21.492555816 +0200
  12908. @@ -0,0 +1,420 @@
  12909. +/*-
  12910. + * Driver for Hifn HIPP-I/II chipset
  12911. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  12912. + *
  12913. + * Redistribution and use in source and binary forms, with or without
  12914. + * modification, are permitted provided that the following conditions
  12915. + * are met:
  12916. + *
  12917. + * 1. Redistributions of source code must retain the above copyright
  12918. + * notice, this list of conditions and the following disclaimer.
  12919. + * 2. Redistributions in binary form must reproduce the above copyright
  12920. + * notice, this list of conditions and the following disclaimer in the
  12921. + * documentation and/or other materials provided with the distribution.
  12922. + * 3. The name of the author may not be used to endorse or promote products
  12923. + * derived from this software without specific prior written permission.
  12924. + *
  12925. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12926. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12927. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12928. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12929. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12930. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12931. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12932. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12933. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12934. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12935. + *
  12936. + * Effort sponsored by Hifn Inc.
  12937. + *
  12938. + */
  12939. +
  12940. +/*
  12941. + * Driver for various Hifn encryption processors.
  12942. + */
  12943. +#ifndef AUTOCONF_INCLUDED
  12944. +#include <linux/config.h>
  12945. +#endif
  12946. +#include <linux/module.h>
  12947. +#include <linux/init.h>
  12948. +#include <linux/list.h>
  12949. +#include <linux/slab.h>
  12950. +#include <linux/wait.h>
  12951. +#include <linux/sched.h>
  12952. +#include <linux/pci.h>
  12953. +#include <linux/delay.h>
  12954. +#include <linux/interrupt.h>
  12955. +#include <linux/spinlock.h>
  12956. +#include <linux/random.h>
  12957. +#include <linux/version.h>
  12958. +#include <linux/skbuff.h>
  12959. +#include <linux/uio.h>
  12960. +#include <linux/sysfs.h>
  12961. +#include <linux/miscdevice.h>
  12962. +#include <asm/io.h>
  12963. +
  12964. +#include <cryptodev.h>
  12965. +
  12966. +#include "hifnHIPPreg.h"
  12967. +#include "hifnHIPPvar.h"
  12968. +
  12969. +#if 1
  12970. +#define DPRINTF(a...) if (hipp_debug) { \
  12971. + printk("%s: ", sc ? \
  12972. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  12973. + printk(a); \
  12974. + } else
  12975. +#else
  12976. +#define DPRINTF(a...)
  12977. +#endif
  12978. +
  12979. +typedef int bus_size_t;
  12980. +
  12981. +static inline int
  12982. +pci_get_revid(struct pci_dev *dev)
  12983. +{
  12984. + u8 rid = 0;
  12985. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  12986. + return rid;
  12987. +}
  12988. +
  12989. +#define debug hipp_debug
  12990. +int hipp_debug = 0;
  12991. +module_param(hipp_debug, int, 0644);
  12992. +MODULE_PARM_DESC(hipp_debug, "Enable debug");
  12993. +
  12994. +int hipp_maxbatch = 1;
  12995. +module_param(hipp_maxbatch, int, 0644);
  12996. +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
  12997. +
  12998. +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  12999. +static void hipp_remove(struct pci_dev *dev);
  13000. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  13001. +static irqreturn_t hipp_intr(int irq, void *arg);
  13002. +#else
  13003. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
  13004. +#endif
  13005. +
  13006. +static int hipp_num_chips = 0;
  13007. +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
  13008. +
  13009. +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
  13010. +static int hipp_freesession(device_t, u_int64_t);
  13011. +static int hipp_process(device_t, struct cryptop *, int);
  13012. +
  13013. +static device_method_t hipp_methods = {
  13014. + /* crypto device methods */
  13015. + DEVMETHOD(cryptodev_newsession, hipp_newsession),
  13016. + DEVMETHOD(cryptodev_freesession,hipp_freesession),
  13017. + DEVMETHOD(cryptodev_process, hipp_process),
  13018. +};
  13019. +
  13020. +static __inline u_int32_t
  13021. +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
  13022. +{
  13023. + u_int32_t v = readl(sc->sc_bar[barno] + reg);
  13024. + //sc->sc_bar0_lastreg = (bus_size_t) -1;
  13025. + return (v);
  13026. +}
  13027. +static __inline void
  13028. +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
  13029. +{
  13030. + writel(val, sc->sc_bar[barno] + reg);
  13031. +}
  13032. +
  13033. +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
  13034. +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
  13035. +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
  13036. +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
  13037. +
  13038. +static int
  13039. +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  13040. +{
  13041. + return EINVAL;
  13042. +}
  13043. +
  13044. +static int
  13045. +hipp_freesession(device_t dev, u_int64_t tid)
  13046. +{
  13047. + return EINVAL;
  13048. +}
  13049. +
  13050. +static int
  13051. +hipp_process(device_t dev, struct cryptop *crp, int hint)
  13052. +{
  13053. + return EINVAL;
  13054. +}
  13055. +
  13056. +static const char*
  13057. +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
  13058. +{
  13059. + char *n = NULL;
  13060. +
  13061. + switch (pci_get_vendor(sc->sc_pcidev)) {
  13062. + case PCI_VENDOR_HIFN:
  13063. + switch (pci_get_device(sc->sc_pcidev)) {
  13064. + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
  13065. + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
  13066. + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
  13067. + }
  13068. + }
  13069. +
  13070. + if(n==NULL) {
  13071. + snprintf(buf, blen, "VID=%02x,PID=%02x",
  13072. + pci_get_vendor(sc->sc_pcidev),
  13073. + pci_get_device(sc->sc_pcidev));
  13074. + } else {
  13075. + buf[0]='\0';
  13076. + strncat(buf, n, blen);
  13077. + }
  13078. + return buf;
  13079. +}
  13080. +
  13081. +struct hipp_fs_entry {
  13082. + struct attribute attr;
  13083. + /* other stuff */
  13084. +};
  13085. +
  13086. +
  13087. +static ssize_t
  13088. +cryptoid_show(struct device *dev,
  13089. + struct device_attribute *attr,
  13090. + char *buf)
  13091. +{
  13092. + struct hipp_softc *sc;
  13093. +
  13094. + sc = pci_get_drvdata(to_pci_dev (dev));
  13095. + return sprintf (buf, "%d\n", sc->sc_cid);
  13096. +}
  13097. +
  13098. +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
  13099. +
  13100. +/*
  13101. + * Attach an interface that successfully probed.
  13102. + */
  13103. +static int
  13104. +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  13105. +{
  13106. + struct hipp_softc *sc = NULL;
  13107. + int i;
  13108. + //char rbase;
  13109. + //u_int16_t ena;
  13110. + int rev;
  13111. + //int rseg;
  13112. + int rc;
  13113. +
  13114. + DPRINTF("%s()\n", __FUNCTION__);
  13115. +
  13116. + if (pci_enable_device(dev) < 0)
  13117. + return(-ENODEV);
  13118. +
  13119. + if (pci_set_mwi(dev))
  13120. + return(-ENODEV);
  13121. +
  13122. + if (!dev->irq) {
  13123. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  13124. + pci_disable_device(dev);
  13125. + return(-ENODEV);
  13126. + }
  13127. +
  13128. + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  13129. + if (!sc)
  13130. + return(-ENOMEM);
  13131. + memset(sc, 0, sizeof(*sc));
  13132. +
  13133. + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
  13134. +
  13135. + sc->sc_pcidev = dev;
  13136. + sc->sc_irq = -1;
  13137. + sc->sc_cid = -1;
  13138. + sc->sc_num = hipp_num_chips++;
  13139. +
  13140. + if (sc->sc_num < HIPP_MAX_CHIPS)
  13141. + hipp_chip_idx[sc->sc_num] = sc;
  13142. +
  13143. + pci_set_drvdata(sc->sc_pcidev, sc);
  13144. +
  13145. + spin_lock_init(&sc->sc_mtx);
  13146. +
  13147. + /*
  13148. + * Setup PCI resources.
  13149. + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
  13150. + * and WRITE_REG_1 macros throughout the driver are used
  13151. + * to permit better debugging.
  13152. + */
  13153. + for(i=0; i<4; i++) {
  13154. + unsigned long mem_start, mem_len;
  13155. + mem_start = pci_resource_start(sc->sc_pcidev, i);
  13156. + mem_len = pci_resource_len(sc->sc_pcidev, i);
  13157. + sc->sc_barphy[i] = (caddr_t)mem_start;
  13158. + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
  13159. + if (!sc->sc_bar[i]) {
  13160. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
  13161. + goto fail;
  13162. + }
  13163. + }
  13164. +
  13165. + //hipp_reset_board(sc, 0);
  13166. + pci_set_master(sc->sc_pcidev);
  13167. +
  13168. + /*
  13169. + * Arrange the interrupt line.
  13170. + */
  13171. + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
  13172. + if (rc) {
  13173. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  13174. + goto fail;
  13175. + }
  13176. + sc->sc_irq = dev->irq;
  13177. +
  13178. + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
  13179. +
  13180. + {
  13181. + char b[32];
  13182. + device_printf(sc->sc_dev, "%s, rev %u",
  13183. + hipp_partname(sc, b, sizeof(b)), rev);
  13184. + }
  13185. +
  13186. +#if 0
  13187. + if (sc->sc_flags & HIFN_IS_7956)
  13188. + printf(", pll=0x%x<%s clk, %ux mult>",
  13189. + sc->sc_pllconfig,
  13190. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  13191. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  13192. +#endif
  13193. + printf("\n");
  13194. +
  13195. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  13196. + if (sc->sc_cid < 0) {
  13197. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  13198. + goto fail;
  13199. + }
  13200. +
  13201. +#if 0 /* cannot work with a non-GPL module */
  13202. + /* make a sysfs entry to let the world know what entry we got */
  13203. + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
  13204. +#endif
  13205. +
  13206. +#if 0
  13207. + init_timer(&sc->sc_tickto);
  13208. + sc->sc_tickto.function = hifn_tick;
  13209. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  13210. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  13211. +#endif
  13212. +
  13213. +#if 0 /* no code here yet ?? */
  13214. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  13215. +#endif
  13216. +
  13217. + return (0);
  13218. +
  13219. +fail:
  13220. + if (sc->sc_cid >= 0)
  13221. + crypto_unregister_all(sc->sc_cid);
  13222. + if (sc->sc_irq != -1)
  13223. + free_irq(sc->sc_irq, sc);
  13224. +
  13225. +#if 0
  13226. + if (sc->sc_dma) {
  13227. + /* Turn off DMA polling */
  13228. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13229. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13230. +
  13231. + pci_free_consistent(sc->sc_pcidev,
  13232. + sizeof(*sc->sc_dma),
  13233. + sc->sc_dma, sc->sc_dma_physaddr);
  13234. + }
  13235. +#endif
  13236. + kfree(sc);
  13237. + return (-ENXIO);
  13238. +}
  13239. +
  13240. +/*
  13241. + * Detach an interface that successfully probed.
  13242. + */
  13243. +static void
  13244. +hipp_remove(struct pci_dev *dev)
  13245. +{
  13246. + struct hipp_softc *sc = pci_get_drvdata(dev);
  13247. + unsigned long l_flags;
  13248. +
  13249. + DPRINTF("%s()\n", __FUNCTION__);
  13250. +
  13251. + /* disable interrupts */
  13252. + HIPP_LOCK(sc);
  13253. +
  13254. +#if 0
  13255. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  13256. + HIFN_UNLOCK(sc);
  13257. +
  13258. + /*XXX other resources */
  13259. + del_timer_sync(&sc->sc_tickto);
  13260. +
  13261. + /* Turn off DMA polling */
  13262. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13263. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13264. +#endif
  13265. +
  13266. + crypto_unregister_all(sc->sc_cid);
  13267. +
  13268. + free_irq(sc->sc_irq, sc);
  13269. +
  13270. +#if 0
  13271. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  13272. + sc->sc_dma, sc->sc_dma_physaddr);
  13273. +#endif
  13274. +}
  13275. +
  13276. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  13277. +static irqreturn_t hipp_intr(int irq, void *arg)
  13278. +#else
  13279. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
  13280. +#endif
  13281. +{
  13282. + struct hipp_softc *sc = arg;
  13283. +
  13284. + sc = sc; /* shut up compiler */
  13285. +
  13286. + return IRQ_HANDLED;
  13287. +}
  13288. +
  13289. +static struct pci_device_id hipp_pci_tbl[] = {
  13290. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
  13291. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  13292. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
  13293. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  13294. +};
  13295. +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
  13296. +
  13297. +static struct pci_driver hipp_driver = {
  13298. + .name = "hipp",
  13299. + .id_table = hipp_pci_tbl,
  13300. + .probe = hipp_probe,
  13301. + .remove = hipp_remove,
  13302. + /* add PM stuff here one day */
  13303. +};
  13304. +
  13305. +static int __init hipp_init (void)
  13306. +{
  13307. + struct hipp_softc *sc = NULL;
  13308. + int rc;
  13309. +
  13310. + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
  13311. +
  13312. + rc = pci_register_driver(&hipp_driver);
  13313. + pci_register_driver_compat(&hipp_driver, rc);
  13314. +
  13315. + return rc;
  13316. +}
  13317. +
  13318. +static void __exit hipp_exit (void)
  13319. +{
  13320. + pci_unregister_driver(&hipp_driver);
  13321. +}
  13322. +
  13323. +module_init(hipp_init);
  13324. +module_exit(hipp_exit);
  13325. +
  13326. +MODULE_LICENSE("BSD");
  13327. +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
  13328. +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
  13329. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.29.1/crypto/ocf/hifn/hifnHIPPreg.h
  13330. --- linux-2.6.29.1.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
  13331. +++ linux-2.6.29.1/crypto/ocf/hifn/hifnHIPPreg.h 2009-04-20 20:01:21.516556358 +0200
  13332. @@ -0,0 +1,46 @@
  13333. +/*-
  13334. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  13335. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  13336. + *
  13337. + * Redistribution and use in source and binary forms, with or without
  13338. + * modification, are permitted provided that the following conditions
  13339. + * are met:
  13340. + *
  13341. + * 1. Redistributions of source code must retain the above copyright
  13342. + * notice, this list of conditions and the following disclaimer.
  13343. + * 2. Redistributions in binary form must reproduce the above copyright
  13344. + * notice, this list of conditions and the following disclaimer in the
  13345. + * documentation and/or other materials provided with the distribution.
  13346. + * 3. The name of the author may not be used to endorse or promote products
  13347. + * derived from this software without specific prior written permission.
  13348. + *
  13349. + *
  13350. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  13351. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  13352. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  13353. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  13354. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  13355. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  13356. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13357. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13358. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  13359. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13360. + *
  13361. + * Effort sponsored by Hifn inc.
  13362. + *
  13363. + */
  13364. +
  13365. +#ifndef __HIFNHIPP_H__
  13366. +#define __HIFNHIPP_H__
  13367. +
  13368. +/*
  13369. + * PCI vendor and device identifiers
  13370. + */
  13371. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  13372. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  13373. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  13374. +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
  13375. +
  13376. +#define HIPP_1_REVID 0x01 /* BOGUS */
  13377. +
  13378. +#endif /* __HIPP_H__ */
  13379. diff -Nur linux-2.6.29.1.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.29.1/crypto/ocf/hifn/hifnHIPPvar.h
  13380. --- linux-2.6.29.1.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
  13381. +++ linux-2.6.29.1/crypto/ocf/hifn/hifnHIPPvar.h 2009-04-20 20:01:21.516556358 +0200
  13382. @@ -0,0 +1,93 @@
  13383. +/*
  13384. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  13385. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
  13386. + *
  13387. + * Redistribution and use in source and binary forms, with or without
  13388. + * modification, are permitted provided that the following conditions
  13389. + * are met:
  13390. + *
  13391. + * 1. Redistributions of source code must retain the above copyright
  13392. + * notice, this list of conditions and the following disclaimer.
  13393. + * 2. Redistributions in binary form must reproduce the above copyright
  13394. + * notice, this list of conditions and the following disclaimer in the
  13395. + * documentation and/or other materials provided with the distribution.
  13396. + * 3. The name of the author may not be used to endorse or promote products
  13397. + * derived from this software without specific prior written permission.
  13398. + *
  13399. + *
  13400. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  13401. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  13402. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  13403. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  13404. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  13405. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  13406. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13407. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13408. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  13409. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13410. + *
  13411. + * Effort sponsored by Hifn inc.
  13412. + *
  13413. + */
  13414. +
  13415. +#ifndef __HIFNHIPPVAR_H__
  13416. +#define __HIFNHIPPVAR_H__
  13417. +
  13418. +#define HIPP_MAX_CHIPS 8
  13419. +
  13420. +/*
  13421. + * Holds data specific to a single Hifn HIPP-I board.
  13422. + */
  13423. +struct hipp_softc {
  13424. + softc_device_decl sc_dev;
  13425. +
  13426. + struct pci_dev *sc_pcidev; /* device backpointer */
  13427. + ocf_iomem_t sc_bar[5];
  13428. + caddr_t sc_barphy[5]; /* physical address */
  13429. + int sc_num; /* for multiple devs */
  13430. + spinlock_t sc_mtx; /* per-instance lock */
  13431. + int32_t sc_cid;
  13432. + int sc_irq;
  13433. +
  13434. +#if 0
  13435. +
  13436. + u_int32_t sc_dmaier;
  13437. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  13438. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  13439. +
  13440. + struct hifn_dma *sc_dma;
  13441. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  13442. +
  13443. + int sc_dmansegs;
  13444. + int sc_maxses;
  13445. + int sc_nsessions;
  13446. + struct hifn_session *sc_sessions;
  13447. + int sc_ramsize;
  13448. + int sc_flags;
  13449. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  13450. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  13451. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  13452. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  13453. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  13454. +
  13455. + struct timer_list sc_tickto; /* for managing DMA */
  13456. +
  13457. + int sc_rngfirst;
  13458. + int sc_rnghz; /* RNG polling frequency */
  13459. +
  13460. + int sc_c_busy; /* command ring busy */
  13461. + int sc_s_busy; /* source data ring busy */
  13462. + int sc_d_busy; /* destination data ring busy */
  13463. + int sc_r_busy; /* result ring busy */
  13464. + int sc_active; /* for initial countdown */
  13465. + int sc_needwakeup; /* ops q'd wating on resources */
  13466. + int sc_curbatch; /* # ops submitted w/o int */
  13467. + int sc_suspended;
  13468. + struct miscdevice sc_miscdev;
  13469. +#endif
  13470. +};
  13471. +
  13472. +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  13473. +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  13474. +
  13475. +#endif /* __HIFNHIPPVAR_H__ */
  13476. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.29.1/crypto/ocf/ixp4xx/Makefile
  13477. --- linux-2.6.29.1.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  13478. +++ linux-2.6.29.1/crypto/ocf/ixp4xx/Makefile 2009-04-20 20:01:21.520556868 +0200
  13479. @@ -0,0 +1,104 @@
  13480. +# for SGlinux builds
  13481. +-include $(ROOTDIR)/modules/.config
  13482. +
  13483. +#
  13484. +# You will need to point this at your Intel ixp425 includes, this portion
  13485. +# of the Makefile only really works under SGLinux with the appropriate libs
  13486. +# installed. They can be downloaded from http://www.snapgear.org/
  13487. +#
  13488. +ifeq ($(CONFIG_CPU_IXP46X),y)
  13489. +IXPLATFORM = ixp46X
  13490. +else
  13491. +ifeq ($(CONFIG_CPU_IXP43X),y)
  13492. +IXPLATFORM = ixp43X
  13493. +else
  13494. +IXPLATFORM = ixp42X
  13495. +endif
  13496. +endif
  13497. +
  13498. +ifdef CONFIG_IXP400_LIB_2_4
  13499. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
  13500. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
  13501. +endif
  13502. +ifdef CONFIG_IXP400_LIB_2_1
  13503. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
  13504. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
  13505. +endif
  13506. +ifdef CONFIG_IXP400_LIB_2_0
  13507. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
  13508. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
  13509. +endif
  13510. +ifdef IX_XSCALE_SW
  13511. +ifdef CONFIG_IXP400_LIB_2_4
  13512. +IXP_CFLAGS = \
  13513. + -I$(ROOTDIR)/. \
  13514. + -I$(IX_XSCALE_SW)/src/include \
  13515. + -I$(OSAL_DIR)/common/include/ \
  13516. + -I$(OSAL_DIR)/common/include/modules/ \
  13517. + -I$(OSAL_DIR)/common/include/modules/ddk/ \
  13518. + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
  13519. + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
  13520. + -I$(OSAL_DIR)/common/os/linux/include/ \
  13521. + -I$(OSAL_DIR)/common/os/linux/include/core/ \
  13522. + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
  13523. + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
  13524. + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
  13525. + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
  13526. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
  13527. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
  13528. + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
  13529. + -DUSE_IXP4XX_CRYPTO
  13530. +else
  13531. +IXP_CFLAGS = \
  13532. + -I$(ROOTDIR)/. \
  13533. + -I$(IX_XSCALE_SW)/src/include \
  13534. + -I$(OSAL_DIR)/ \
  13535. + -I$(OSAL_DIR)/os/linux/include/ \
  13536. + -I$(OSAL_DIR)/os/linux/include/modules/ \
  13537. + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
  13538. + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
  13539. + -I$(OSAL_DIR)/os/linux/include/core/ \
  13540. + -I$(OSAL_DIR)/os/linux/include/platforms/ \
  13541. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
  13542. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
  13543. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
  13544. + -I$(OSAL_DIR)/os/linux/include/core/ \
  13545. + -I$(OSAL_DIR)/include/ \
  13546. + -I$(OSAL_DIR)/include/modules/ \
  13547. + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
  13548. + -I$(OSAL_DIR)/include/modules/ioMem/ \
  13549. + -I$(OSAL_DIR)/include/platforms/ \
  13550. + -I$(OSAL_DIR)/include/platforms/ixp400/ \
  13551. + -DUSE_IXP4XX_CRYPTO
  13552. +endif
  13553. +endif
  13554. +ifdef CONFIG_IXP400_LIB_1_4
  13555. +IXP_CFLAGS = \
  13556. + -I$(ROOTDIR)/. \
  13557. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
  13558. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
  13559. + -DUSE_IXP4XX_CRYPTO
  13560. +endif
  13561. +ifndef IXPDIR
  13562. +IXPDIR = ixp-version-is-not-supported
  13563. +endif
  13564. +
  13565. +ifeq ($(CONFIG_CPU_IXP46X),y)
  13566. +IXP_CFLAGS += -D__ixp46X
  13567. +else
  13568. +ifeq ($(CONFIG_CPU_IXP43X),y)
  13569. +IXP_CFLAGS += -D__ixp43X
  13570. +else
  13571. +IXP_CFLAGS += -D__ixp42X
  13572. +endif
  13573. +endif
  13574. +
  13575. +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
  13576. +
  13577. +obj ?= .
  13578. +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
  13579. +
  13580. +ifdef TOPDIR
  13581. +-include $(TOPDIR)/Rules.make
  13582. +endif
  13583. +
  13584. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.29.1/crypto/ocf/ixp4xx/ixp4xx.c
  13585. --- linux-2.6.29.1.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
  13586. +++ linux-2.6.29.1/crypto/ocf/ixp4xx/ixp4xx.c 2009-04-20 20:01:21.520556868 +0200
  13587. @@ -0,0 +1,1328 @@
  13588. +/*
  13589. + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
  13590. + * This driver requires the IXP400 Access Library that is available
  13591. + * from Intel in order to operate (or compile).
  13592. + *
  13593. + * Written by David McCullough <david_mccullough@securecomputing.com>
  13594. + * Copyright (C) 2006-2007 David McCullough
  13595. + * Copyright (C) 2004-2005 Intel Corporation.
  13596. + *
  13597. + * LICENSE TERMS
  13598. + *
  13599. + * The free distribution and use of this software in both source and binary
  13600. + * form is allowed (with or without changes) provided that:
  13601. + *
  13602. + * 1. distributions of this source code include the above copyright
  13603. + * notice, this list of conditions and the following disclaimer;
  13604. + *
  13605. + * 2. distributions in binary form include the above copyright
  13606. + * notice, this list of conditions and the following disclaimer
  13607. + * in the documentation and/or other associated materials;
  13608. + *
  13609. + * 3. the copyright holder's name is not used to endorse products
  13610. + * built using this software without specific written permission.
  13611. + *
  13612. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  13613. + * may be distributed under the terms of the GNU General Public License (GPL),
  13614. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  13615. + *
  13616. + * DISCLAIMER
  13617. + *
  13618. + * This software is provided 'as is' with no explicit or implied warranties
  13619. + * in respect of its properties, including, but not limited to, correctness
  13620. + * and/or fitness for purpose.
  13621. + */
  13622. +
  13623. +#ifndef AUTOCONF_INCLUDED
  13624. +#include <linux/config.h>
  13625. +#endif
  13626. +#include <linux/module.h>
  13627. +#include <linux/init.h>
  13628. +#include <linux/list.h>
  13629. +#include <linux/slab.h>
  13630. +#include <linux/sched.h>
  13631. +#include <linux/wait.h>
  13632. +#include <linux/crypto.h>
  13633. +#include <linux/interrupt.h>
  13634. +#include <asm/scatterlist.h>
  13635. +
  13636. +#include <IxTypes.h>
  13637. +#include <IxOsBuffMgt.h>
  13638. +#include <IxNpeDl.h>
  13639. +#include <IxCryptoAcc.h>
  13640. +#include <IxQMgr.h>
  13641. +#include <IxOsServices.h>
  13642. +#include <IxOsCacheMMU.h>
  13643. +
  13644. +#include <cryptodev.h>
  13645. +#include <uio.h>
  13646. +
  13647. +#ifndef IX_MBUF_PRIV
  13648. +#define IX_MBUF_PRIV(x) ((x)->priv)
  13649. +#endif
  13650. +
  13651. +struct ixp_data;
  13652. +
  13653. +struct ixp_q {
  13654. + struct list_head ixp_q_list;
  13655. + struct ixp_data *ixp_q_data;
  13656. + struct cryptop *ixp_q_crp;
  13657. + struct cryptodesc *ixp_q_ccrd;
  13658. + struct cryptodesc *ixp_q_acrd;
  13659. + IX_MBUF ixp_q_mbuf;
  13660. + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
  13661. + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
  13662. + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
  13663. + unsigned char *ixp_q_iv;
  13664. +};
  13665. +
  13666. +struct ixp_data {
  13667. + int ixp_registered; /* is the context registered */
  13668. + int ixp_crd_flags; /* detect direction changes */
  13669. +
  13670. + int ixp_cipher_alg;
  13671. + int ixp_auth_alg;
  13672. +
  13673. + UINT32 ixp_ctx_id;
  13674. + UINT32 ixp_hash_key_id; /* used when hashing */
  13675. + IxCryptoAccCtx ixp_ctx;
  13676. + IX_MBUF ixp_pri_mbuf;
  13677. + IX_MBUF ixp_sec_mbuf;
  13678. +
  13679. + struct work_struct ixp_pending_work;
  13680. + struct work_struct ixp_registration_work;
  13681. + struct list_head ixp_q; /* unprocessed requests */
  13682. +};
  13683. +
  13684. +#ifdef __ixp46X
  13685. +
  13686. +#define MAX_IOP_SIZE 64 /* words */
  13687. +#define MAX_OOP_SIZE 128
  13688. +
  13689. +#define MAX_PARAMS 3
  13690. +
  13691. +struct ixp_pkq {
  13692. + struct list_head pkq_list;
  13693. + struct cryptkop *pkq_krp;
  13694. +
  13695. + IxCryptoAccPkeEauInOperands pkq_op;
  13696. + IxCryptoAccPkeEauOpResult pkq_result;
  13697. +
  13698. + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
  13699. + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
  13700. + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
  13701. + UINT32 pkq_obuf[MAX_OOP_SIZE];
  13702. +};
  13703. +
  13704. +static LIST_HEAD(ixp_pkq); /* current PK wait list */
  13705. +static struct ixp_pkq *ixp_pk_cur;
  13706. +static spinlock_t ixp_pkq_lock;
  13707. +
  13708. +#endif /* __ixp46X */
  13709. +
  13710. +static int ixp_blocked = 0;
  13711. +
  13712. +static int32_t ixp_id = -1;
  13713. +static struct ixp_data **ixp_sessions = NULL;
  13714. +static u_int32_t ixp_sesnum = 0;
  13715. +
  13716. +static int ixp_process(device_t, struct cryptop *, int);
  13717. +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
  13718. +static int ixp_freesession(device_t, u_int64_t);
  13719. +#ifdef __ixp46X
  13720. +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
  13721. +#endif
  13722. +
  13723. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  13724. +static kmem_cache_t *qcache;
  13725. +#else
  13726. +static struct kmem_cache *qcache;
  13727. +#endif
  13728. +
  13729. +#define debug ixp_debug
  13730. +static int ixp_debug = 0;
  13731. +module_param(ixp_debug, int, 0644);
  13732. +MODULE_PARM_DESC(ixp_debug, "Enable debug");
  13733. +
  13734. +static int ixp_init_crypto = 1;
  13735. +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
  13736. +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
  13737. +
  13738. +static void ixp_process_pending(void *arg);
  13739. +static void ixp_registration(void *arg);
  13740. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13741. +static void ixp_process_pending_wq(struct work_struct *work);
  13742. +static void ixp_registration_wq(struct work_struct *work);
  13743. +#endif
  13744. +
  13745. +/*
  13746. + * dummy device structure
  13747. + */
  13748. +
  13749. +static struct {
  13750. + softc_device_decl sc_dev;
  13751. +} ixpdev;
  13752. +
  13753. +static device_method_t ixp_methods = {
  13754. + /* crypto device methods */
  13755. + DEVMETHOD(cryptodev_newsession, ixp_newsession),
  13756. + DEVMETHOD(cryptodev_freesession,ixp_freesession),
  13757. + DEVMETHOD(cryptodev_process, ixp_process),
  13758. +#ifdef __ixp46X
  13759. + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
  13760. +#endif
  13761. +};
  13762. +
  13763. +/*
  13764. + * Generate a new software session.
  13765. + */
  13766. +static int
  13767. +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  13768. +{
  13769. + struct ixp_data *ixp;
  13770. + u_int32_t i;
  13771. +#define AUTH_LEN(cri, def) \
  13772. + (cri->cri_mlen ? cri->cri_mlen : (def))
  13773. +
  13774. + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
  13775. + if (sid == NULL || cri == NULL) {
  13776. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  13777. + return EINVAL;
  13778. + }
  13779. +
  13780. + if (ixp_sessions) {
  13781. + for (i = 1; i < ixp_sesnum; i++)
  13782. + if (ixp_sessions[i] == NULL)
  13783. + break;
  13784. + } else
  13785. + i = 1; /* NB: to silence compiler warning */
  13786. +
  13787. + if (ixp_sessions == NULL || i == ixp_sesnum) {
  13788. + struct ixp_data **ixpd;
  13789. +
  13790. + if (ixp_sessions == NULL) {
  13791. + i = 1; /* We leave ixp_sessions[0] empty */
  13792. + ixp_sesnum = CRYPTO_SW_SESSIONS;
  13793. + } else
  13794. + ixp_sesnum *= 2;
  13795. +
  13796. + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
  13797. + if (ixpd == NULL) {
  13798. + /* Reset session number */
  13799. + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
  13800. + ixp_sesnum = 0;
  13801. + else
  13802. + ixp_sesnum /= 2;
  13803. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  13804. + return ENOBUFS;
  13805. + }
  13806. + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
  13807. +
  13808. + /* Copy existing sessions */
  13809. + if (ixp_sessions) {
  13810. + memcpy(ixpd, ixp_sessions,
  13811. + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
  13812. + kfree(ixp_sessions);
  13813. + }
  13814. +
  13815. + ixp_sessions = ixpd;
  13816. + }
  13817. +
  13818. + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
  13819. + SLAB_ATOMIC);
  13820. + if (ixp_sessions[i] == NULL) {
  13821. + ixp_freesession(NULL, i);
  13822. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  13823. + return ENOBUFS;
  13824. + }
  13825. +
  13826. + *sid = i;
  13827. +
  13828. + ixp = ixp_sessions[i];
  13829. + memset(ixp, 0, sizeof(*ixp));
  13830. +
  13831. + ixp->ixp_cipher_alg = -1;
  13832. + ixp->ixp_auth_alg = -1;
  13833. + ixp->ixp_ctx_id = -1;
  13834. + INIT_LIST_HEAD(&ixp->ixp_q);
  13835. +
  13836. + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  13837. +
  13838. + while (cri) {
  13839. + switch (cri->cri_alg) {
  13840. + case CRYPTO_DES_CBC:
  13841. + ixp->ixp_cipher_alg = cri->cri_alg;
  13842. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
  13843. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  13844. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  13845. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  13846. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  13847. + IX_CRYPTO_ACC_DES_IV_64;
  13848. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  13849. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13850. + break;
  13851. +
  13852. + case CRYPTO_3DES_CBC:
  13853. + ixp->ixp_cipher_alg = cri->cri_alg;
  13854. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  13855. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  13856. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  13857. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  13858. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  13859. + IX_CRYPTO_ACC_DES_IV_64;
  13860. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  13861. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13862. + break;
  13863. +
  13864. + case CRYPTO_RIJNDAEL128_CBC:
  13865. + ixp->ixp_cipher_alg = cri->cri_alg;
  13866. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
  13867. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  13868. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  13869. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
  13870. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
  13871. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  13872. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13873. + break;
  13874. +
  13875. + case CRYPTO_MD5:
  13876. + case CRYPTO_MD5_HMAC:
  13877. + ixp->ixp_auth_alg = cri->cri_alg;
  13878. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
  13879. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
  13880. + ixp->ixp_ctx.authCtx.aadLen = 0;
  13881. + /* Only MD5_HMAC needs a key */
  13882. + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
  13883. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  13884. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  13885. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  13886. + printk(
  13887. + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
  13888. + cri->cri_klen);
  13889. + ixp_freesession(NULL, i);
  13890. + return EINVAL;
  13891. + }
  13892. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  13893. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13894. + }
  13895. + break;
  13896. +
  13897. + case CRYPTO_SHA1:
  13898. + case CRYPTO_SHA1_HMAC:
  13899. + ixp->ixp_auth_alg = cri->cri_alg;
  13900. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  13901. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
  13902. + ixp->ixp_ctx.authCtx.aadLen = 0;
  13903. + /* Only SHA1_HMAC needs a key */
  13904. + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
  13905. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  13906. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  13907. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  13908. + printk(
  13909. + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
  13910. + cri->cri_klen);
  13911. + ixp_freesession(NULL, i);
  13912. + return EINVAL;
  13913. + }
  13914. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  13915. + cri->cri_key, (cri->cri_klen + 7) / 8);
  13916. + }
  13917. + break;
  13918. +
  13919. + default:
  13920. + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
  13921. + ixp_freesession(NULL, i);
  13922. + return EINVAL;
  13923. + }
  13924. + cri = cri->cri_next;
  13925. + }
  13926. +
  13927. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  13928. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
  13929. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
  13930. +#else
  13931. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
  13932. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
  13933. +#endif
  13934. +
  13935. + return 0;
  13936. +}
  13937. +
  13938. +
  13939. +/*
  13940. + * Free a session.
  13941. + */
  13942. +static int
  13943. +ixp_freesession(device_t dev, u_int64_t tid)
  13944. +{
  13945. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  13946. +
  13947. + dprintk("%s()\n", __FUNCTION__);
  13948. + if (sid > ixp_sesnum || ixp_sessions == NULL ||
  13949. + ixp_sessions[sid] == NULL) {
  13950. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  13951. + return EINVAL;
  13952. + }
  13953. +
  13954. + /* Silently accept and return */
  13955. + if (sid == 0)
  13956. + return 0;
  13957. +
  13958. + if (ixp_sessions[sid]) {
  13959. + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
  13960. + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
  13961. + ixp_sessions[sid]->ixp_ctx_id = -1;
  13962. + }
  13963. +
  13964. + flush_scheduled_work();
  13965. +
  13966. + kfree(ixp_sessions[sid]);
  13967. + }
  13968. + ixp_sessions[sid] = NULL;
  13969. + if (ixp_blocked) {
  13970. + ixp_blocked = 0;
  13971. + crypto_unblock(ixp_id, CRYPTO_SYMQ);
  13972. + }
  13973. + return 0;
  13974. +}
  13975. +
  13976. +
  13977. +/*
  13978. + * callback for when hash processing is complete
  13979. + */
  13980. +
  13981. +static void
  13982. +ixp_hash_perform_cb(
  13983. + UINT32 hash_key_id,
  13984. + IX_MBUF *bufp,
  13985. + IxCryptoAccStatus status)
  13986. +{
  13987. + struct ixp_q *q;
  13988. +
  13989. + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
  13990. +
  13991. + if (bufp == NULL) {
  13992. + printk("ixp: NULL buf in %s\n", __FUNCTION__);
  13993. + return;
  13994. + }
  13995. +
  13996. + q = IX_MBUF_PRIV(bufp);
  13997. + if (q == NULL) {
  13998. + printk("ixp: NULL priv in %s\n", __FUNCTION__);
  13999. + return;
  14000. + }
  14001. +
  14002. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14003. + /* On success, need to copy hash back into original client buffer */
  14004. + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
  14005. + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
  14006. + SHA1_HASH_LEN : MD5_HASH_LEN);
  14007. + }
  14008. + else {
  14009. + printk("ixp: hash perform failed status=%d\n", status);
  14010. + q->ixp_q_crp->crp_etype = EINVAL;
  14011. + }
  14012. +
  14013. + /* Free internal buffer used for hashing */
  14014. + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
  14015. +
  14016. + crypto_done(q->ixp_q_crp);
  14017. + kmem_cache_free(qcache, q);
  14018. +}
  14019. +
  14020. +/*
  14021. + * setup a request and perform it
  14022. + */
  14023. +static void
  14024. +ixp_q_process(struct ixp_q *q)
  14025. +{
  14026. + IxCryptoAccStatus status;
  14027. + struct ixp_data *ixp = q->ixp_q_data;
  14028. + int auth_off = 0;
  14029. + int auth_len = 0;
  14030. + int crypt_off = 0;
  14031. + int crypt_len = 0;
  14032. + int icv_off = 0;
  14033. + char *crypt_func;
  14034. +
  14035. + dprintk("%s(%p)\n", __FUNCTION__, q);
  14036. +
  14037. + if (q->ixp_q_ccrd) {
  14038. + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  14039. + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
  14040. + } else {
  14041. + q->ixp_q_iv = q->ixp_q_iv_data;
  14042. + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
  14043. + q->ixp_q_ccrd->crd_inject,
  14044. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
  14045. + (caddr_t) q->ixp_q_iv);
  14046. + }
  14047. +
  14048. + if (q->ixp_q_acrd) {
  14049. + auth_off = q->ixp_q_acrd->crd_skip;
  14050. + auth_len = q->ixp_q_acrd->crd_len;
  14051. + icv_off = q->ixp_q_acrd->crd_inject;
  14052. + }
  14053. +
  14054. + crypt_off = q->ixp_q_ccrd->crd_skip;
  14055. + crypt_len = q->ixp_q_ccrd->crd_len;
  14056. + } else { /* if (q->ixp_q_acrd) */
  14057. + auth_off = q->ixp_q_acrd->crd_skip;
  14058. + auth_len = q->ixp_q_acrd->crd_len;
  14059. + icv_off = q->ixp_q_acrd->crd_inject;
  14060. + }
  14061. +
  14062. + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
  14063. + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
  14064. + if (skb_shinfo(skb)->nr_frags) {
  14065. + /*
  14066. + * DAVIDM fix this limitation one day by using
  14067. + * a buffer pool and chaining, it is not currently
  14068. + * needed for current user/kernel space acceleration
  14069. + */
  14070. + printk("ixp: Cannot handle fragmented skb's yet !\n");
  14071. + q->ixp_q_crp->crp_etype = ENOENT;
  14072. + goto done;
  14073. + }
  14074. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  14075. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
  14076. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
  14077. + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
  14078. + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
  14079. + if (uiop->uio_iovcnt != 1) {
  14080. + /*
  14081. + * DAVIDM fix this limitation one day by using
  14082. + * a buffer pool and chaining, it is not currently
  14083. + * needed for current user/kernel space acceleration
  14084. + */
  14085. + printk("ixp: Cannot handle more than 1 iovec yet !\n");
  14086. + q->ixp_q_crp->crp_etype = ENOENT;
  14087. + goto done;
  14088. + }
  14089. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  14090. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
  14091. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
  14092. + } else /* contig buffer */ {
  14093. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  14094. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
  14095. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
  14096. + }
  14097. +
  14098. + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
  14099. +
  14100. + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
  14101. + /*
  14102. + * For SHA1 and MD5 hash, need to create an internal buffer that is big
  14103. + * enough to hold the original data + the appropriate padding for the
  14104. + * hash algorithm.
  14105. + */
  14106. + UINT8 *tbuf = NULL;
  14107. +
  14108. + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
  14109. + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
  14110. + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
  14111. +
  14112. + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
  14113. + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
  14114. + IX_MBUF_MLEN(&q->ixp_q_mbuf));
  14115. + q->ixp_q_crp->crp_etype = ENOMEM;
  14116. + goto done;
  14117. + }
  14118. + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
  14119. +
  14120. + /* Set location in client buffer to copy hash into */
  14121. + q->ixp_hash_dest =
  14122. + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
  14123. +
  14124. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
  14125. +
  14126. + /* Set location in internal buffer for where hash starts */
  14127. + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
  14128. +
  14129. + crypt_func = "ixCryptoAccHashPerform";
  14130. + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
  14131. + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
  14132. + &ixp->ixp_hash_key_id);
  14133. + }
  14134. + else {
  14135. + crypt_func = "ixCryptoAccAuthCryptPerform";
  14136. + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
  14137. + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
  14138. + q->ixp_q_iv);
  14139. + }
  14140. +
  14141. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  14142. + return;
  14143. +
  14144. + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
  14145. + q->ixp_q_crp->crp_etype = ENOMEM;
  14146. + goto done;
  14147. + }
  14148. +
  14149. + printk("ixp: %s failed %u\n", crypt_func, status);
  14150. + q->ixp_q_crp->crp_etype = EINVAL;
  14151. +
  14152. +done:
  14153. + crypto_done(q->ixp_q_crp);
  14154. + kmem_cache_free(qcache, q);
  14155. +}
  14156. +
  14157. +
  14158. +/*
  14159. + * because we cannot process the Q from the Register callback
  14160. + * we do it here on a task Q.
  14161. + */
  14162. +
  14163. +static void
  14164. +ixp_process_pending(void *arg)
  14165. +{
  14166. + struct ixp_data *ixp = arg;
  14167. + struct ixp_q *q = NULL;
  14168. +
  14169. + dprintk("%s(%p)\n", __FUNCTION__, arg);
  14170. +
  14171. + if (!ixp)
  14172. + return;
  14173. +
  14174. + while (!list_empty(&ixp->ixp_q)) {
  14175. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  14176. + list_del(&q->ixp_q_list);
  14177. + ixp_q_process(q);
  14178. + }
  14179. +}
  14180. +
  14181. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  14182. +static void
  14183. +ixp_process_pending_wq(struct work_struct *work)
  14184. +{
  14185. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  14186. + ixp_pending_work);
  14187. + ixp_process_pending(ixp);
  14188. +}
  14189. +#endif
  14190. +
  14191. +/*
  14192. + * callback for when context registration is complete
  14193. + */
  14194. +
  14195. +static void
  14196. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  14197. +{
  14198. + int i;
  14199. + struct ixp_data *ixp;
  14200. + struct ixp_q *q;
  14201. +
  14202. + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
  14203. +
  14204. + /*
  14205. + * free any buffer passed in to this routine
  14206. + */
  14207. + if (bufp) {
  14208. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  14209. + kfree(IX_MBUF_MDATA(bufp));
  14210. + IX_MBUF_MDATA(bufp) = NULL;
  14211. + }
  14212. +
  14213. + for (i = 0; i < ixp_sesnum; i++) {
  14214. + ixp = ixp_sessions[i];
  14215. + if (ixp && ixp->ixp_ctx_id == ctx_id)
  14216. + break;
  14217. + }
  14218. + if (i >= ixp_sesnum) {
  14219. + printk("ixp: invalid context id %d\n", ctx_id);
  14220. + return;
  14221. + }
  14222. +
  14223. + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
  14224. + /* this is normal to free the first of two buffers */
  14225. + dprintk("ixp: register not finished yet.\n");
  14226. + return;
  14227. + }
  14228. +
  14229. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  14230. + printk("ixp: register failed 0x%x\n", status);
  14231. + while (!list_empty(&ixp->ixp_q)) {
  14232. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  14233. + list_del(&q->ixp_q_list);
  14234. + q->ixp_q_crp->crp_etype = EINVAL;
  14235. + crypto_done(q->ixp_q_crp);
  14236. + kmem_cache_free(qcache, q);
  14237. + }
  14238. + return;
  14239. + }
  14240. +
  14241. + /*
  14242. + * we are now registered, we cannot start processing the Q here
  14243. + * or we get strange errors with AES (DES/3DES seem to be ok).
  14244. + */
  14245. + ixp->ixp_registered = 1;
  14246. + schedule_work(&ixp->ixp_pending_work);
  14247. +}
  14248. +
  14249. +
  14250. +/*
  14251. + * callback for when data processing is complete
  14252. + */
  14253. +
  14254. +static void
  14255. +ixp_perform_cb(
  14256. + UINT32 ctx_id,
  14257. + IX_MBUF *sbufp,
  14258. + IX_MBUF *dbufp,
  14259. + IxCryptoAccStatus status)
  14260. +{
  14261. + struct ixp_q *q;
  14262. +
  14263. + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
  14264. + dbufp, status);
  14265. +
  14266. + if (sbufp == NULL) {
  14267. + printk("ixp: NULL sbuf in ixp_perform_cb\n");
  14268. + return;
  14269. + }
  14270. +
  14271. + q = IX_MBUF_PRIV(sbufp);
  14272. + if (q == NULL) {
  14273. + printk("ixp: NULL priv in ixp_perform_cb\n");
  14274. + return;
  14275. + }
  14276. +
  14277. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14278. + printk("ixp: perform failed status=%d\n", status);
  14279. + q->ixp_q_crp->crp_etype = EINVAL;
  14280. + }
  14281. +
  14282. + crypto_done(q->ixp_q_crp);
  14283. + kmem_cache_free(qcache, q);
  14284. +}
  14285. +
  14286. +
  14287. +/*
  14288. + * registration is not callable at IRQ time, so we defer
  14289. + * to a task queue, this routines completes the registration for us
  14290. + * when the task queue runs
  14291. + *
  14292. + * Unfortunately this means we cannot tell OCF that the driver is blocked,
  14293. + * we do that on the next request.
  14294. + */
  14295. +
  14296. +static void
  14297. +ixp_registration(void *arg)
  14298. +{
  14299. + struct ixp_data *ixp = arg;
  14300. + struct ixp_q *q = NULL;
  14301. + IX_MBUF *pri = NULL, *sec = NULL;
  14302. + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
  14303. +
  14304. + if (!ixp) {
  14305. + printk("ixp: ixp_registration with no arg\n");
  14306. + return;
  14307. + }
  14308. +
  14309. + if (ixp->ixp_ctx_id != -1) {
  14310. + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
  14311. + ixp->ixp_ctx_id = -1;
  14312. + }
  14313. +
  14314. + if (list_empty(&ixp->ixp_q)) {
  14315. + printk("ixp: ixp_registration with no Q\n");
  14316. + return;
  14317. + }
  14318. +
  14319. + /*
  14320. + * setup the primary and secondary buffers
  14321. + */
  14322. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  14323. + if (q->ixp_q_acrd) {
  14324. + pri = &ixp->ixp_pri_mbuf;
  14325. + sec = &ixp->ixp_sec_mbuf;
  14326. + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
  14327. + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  14328. + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
  14329. + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  14330. + }
  14331. +
  14332. + /* Only need to register if a crypt op or HMAC op */
  14333. + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
  14334. + ixp->ixp_auth_alg == CRYPTO_MD5)) {
  14335. + status = ixCryptoAccCtxRegister(
  14336. + &ixp->ixp_ctx,
  14337. + pri, sec,
  14338. + ixp_register_cb,
  14339. + ixp_perform_cb,
  14340. + &ixp->ixp_ctx_id);
  14341. + }
  14342. + else {
  14343. + /* Otherwise we start processing pending q */
  14344. + schedule_work(&ixp->ixp_pending_work);
  14345. + }
  14346. +
  14347. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  14348. + return;
  14349. +
  14350. + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
  14351. + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
  14352. + ixp_blocked = 1;
  14353. + /* perhaps we should return EGAIN on queued ops ? */
  14354. + return;
  14355. + }
  14356. +
  14357. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  14358. + ixp->ixp_ctx_id = -1;
  14359. +
  14360. + /*
  14361. + * everything waiting is toasted
  14362. + */
  14363. + while (!list_empty(&ixp->ixp_q)) {
  14364. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  14365. + list_del(&q->ixp_q_list);
  14366. + q->ixp_q_crp->crp_etype = ENOENT;
  14367. + crypto_done(q->ixp_q_crp);
  14368. + kmem_cache_free(qcache, q);
  14369. + }
  14370. +}
  14371. +
  14372. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  14373. +static void
  14374. +ixp_registration_wq(struct work_struct *work)
  14375. +{
  14376. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  14377. + ixp_registration_work);
  14378. + ixp_registration(ixp);
  14379. +}
  14380. +#endif
  14381. +
  14382. +/*
  14383. + * Process a request.
  14384. + */
  14385. +static int
  14386. +ixp_process(device_t dev, struct cryptop *crp, int hint)
  14387. +{
  14388. + struct ixp_data *ixp;
  14389. + unsigned int lid;
  14390. + struct ixp_q *q = NULL;
  14391. + int status;
  14392. +
  14393. + dprintk("%s()\n", __FUNCTION__);
  14394. +
  14395. + /* Sanity check */
  14396. + if (crp == NULL) {
  14397. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  14398. + return EINVAL;
  14399. + }
  14400. +
  14401. + crp->crp_etype = 0;
  14402. +
  14403. + if (ixp_blocked)
  14404. + return ERESTART;
  14405. +
  14406. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  14407. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  14408. + crp->crp_etype = EINVAL;
  14409. + goto done;
  14410. + }
  14411. +
  14412. + /*
  14413. + * find the session we are using
  14414. + */
  14415. +
  14416. + lid = crp->crp_sid & 0xffffffff;
  14417. + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
  14418. + ixp_sessions[lid] == NULL) {
  14419. + crp->crp_etype = ENOENT;
  14420. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  14421. + goto done;
  14422. + }
  14423. + ixp = ixp_sessions[lid];
  14424. +
  14425. + /*
  14426. + * setup a new request ready for queuing
  14427. + */
  14428. + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
  14429. + if (q == NULL) {
  14430. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  14431. + crp->crp_etype = ENOMEM;
  14432. + goto done;
  14433. + }
  14434. + /*
  14435. + * save some cycles by only zeroing the important bits
  14436. + */
  14437. + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
  14438. + q->ixp_q_ccrd = NULL;
  14439. + q->ixp_q_acrd = NULL;
  14440. + q->ixp_q_crp = crp;
  14441. + q->ixp_q_data = ixp;
  14442. +
  14443. + /*
  14444. + * point the cipher and auth descriptors appropriately
  14445. + * check that we have something to do
  14446. + */
  14447. + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
  14448. + q->ixp_q_ccrd = crp->crp_desc;
  14449. + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
  14450. + q->ixp_q_acrd = crp->crp_desc;
  14451. + else {
  14452. + crp->crp_etype = ENOENT;
  14453. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  14454. + goto done;
  14455. + }
  14456. + if (crp->crp_desc->crd_next) {
  14457. + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
  14458. + q->ixp_q_ccrd = crp->crp_desc->crd_next;
  14459. + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
  14460. + q->ixp_q_acrd = crp->crp_desc->crd_next;
  14461. + else {
  14462. + crp->crp_etype = ENOENT;
  14463. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  14464. + goto done;
  14465. + }
  14466. + }
  14467. +
  14468. + /*
  14469. + * If there is a direction change for this context then we mark it as
  14470. + * unregistered and re-register is for the new direction. This is not
  14471. + * a very expensive operation and currently only tends to happen when
  14472. + * user-space application are doing benchmarks
  14473. + *
  14474. + * DM - we should be checking for pending requests before unregistering.
  14475. + */
  14476. + if (q->ixp_q_ccrd && ixp->ixp_registered &&
  14477. + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
  14478. + dprintk("%s - detected direction change on session\n", __FUNCTION__);
  14479. + ixp->ixp_registered = 0;
  14480. + }
  14481. +
  14482. + /*
  14483. + * if we are registered, call straight into the perform code
  14484. + */
  14485. + if (ixp->ixp_registered) {
  14486. + ixp_q_process(q);
  14487. + return 0;
  14488. + }
  14489. +
  14490. + /*
  14491. + * the only part of the context not set in newsession is the direction
  14492. + * dependent parts
  14493. + */
  14494. + if (q->ixp_q_ccrd) {
  14495. + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
  14496. + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
  14497. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  14498. + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
  14499. + } else {
  14500. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  14501. + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
  14502. + }
  14503. + } else {
  14504. + /* q->ixp_q_acrd must be set if we are here */
  14505. + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
  14506. + }
  14507. +
  14508. + status = list_empty(&ixp->ixp_q);
  14509. + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
  14510. + if (status)
  14511. + schedule_work(&ixp->ixp_registration_work);
  14512. + return 0;
  14513. +
  14514. +done:
  14515. + if (q)
  14516. + kmem_cache_free(qcache, q);
  14517. + crypto_done(crp);
  14518. + return 0;
  14519. +}
  14520. +
  14521. +
  14522. +#ifdef __ixp46X
  14523. +/*
  14524. + * key processing support for the ixp465
  14525. + */
  14526. +
  14527. +
  14528. +/*
  14529. + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
  14530. + * assume zeroed and only copy bits that are significant
  14531. + */
  14532. +
  14533. +static int
  14534. +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
  14535. +{
  14536. + unsigned char *src = (unsigned char *) p->crp_p;
  14537. + unsigned char *dst;
  14538. + int len, bits = p->crp_nbits;
  14539. +
  14540. + dprintk("%s()\n", __FUNCTION__);
  14541. +
  14542. + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
  14543. + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
  14544. + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
  14545. + return -1;
  14546. + }
  14547. +
  14548. + len = (bits + 31) / 32; /* the number UINT32's needed */
  14549. +
  14550. + dst = (unsigned char *) &buf[len];
  14551. + dst--;
  14552. +
  14553. + while (bits > 0) {
  14554. + *dst-- = *src++;
  14555. + bits -= 8;
  14556. + }
  14557. +
  14558. +#if 0 /* no need to zero remaining bits as it is done during request alloc */
  14559. + while (dst > (unsigned char *) buf)
  14560. + *dst-- = '\0';
  14561. +#endif
  14562. +
  14563. + op->pData = buf;
  14564. + op->dataLen = len;
  14565. + return 0;
  14566. +}
  14567. +
  14568. +/*
  14569. + * copy out the result, be as forgiving as we can about small output buffers
  14570. + */
  14571. +
  14572. +static int
  14573. +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
  14574. +{
  14575. + unsigned char *dst = (unsigned char *) p->crp_p;
  14576. + unsigned char *src = (unsigned char *) buf;
  14577. + int len, z, bits = p->crp_nbits;
  14578. +
  14579. + dprintk("%s()\n", __FUNCTION__);
  14580. +
  14581. + len = op->dataLen * sizeof(UINT32);
  14582. +
  14583. + /* skip leading zeroes to be small buffer friendly */
  14584. + z = 0;
  14585. + while (z < len && src[z] == '\0')
  14586. + z++;
  14587. +
  14588. + src += len;
  14589. + src--;
  14590. + len -= z;
  14591. +
  14592. + while (len > 0 && bits > 0) {
  14593. + *dst++ = *src--;
  14594. + len--;
  14595. + bits -= 8;
  14596. + }
  14597. +
  14598. + while (bits > 0) {
  14599. + *dst++ = '\0';
  14600. + bits -= 8;
  14601. + }
  14602. +
  14603. + if (len > 0) {
  14604. + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
  14605. + __FUNCTION__, len, z, p->crp_nbits / 8);
  14606. + return -1;
  14607. + }
  14608. +
  14609. + return 0;
  14610. +}
  14611. +
  14612. +
  14613. +/*
  14614. + * the parameter offsets for exp_mod
  14615. + */
  14616. +
  14617. +#define IXP_PARAM_BASE 0
  14618. +#define IXP_PARAM_EXP 1
  14619. +#define IXP_PARAM_MOD 2
  14620. +#define IXP_PARAM_RES 3
  14621. +
  14622. +/*
  14623. + * key processing complete callback, is also used to start processing
  14624. + * by passing a NULL for pResult
  14625. + */
  14626. +
  14627. +static void
  14628. +ixp_kperform_cb(
  14629. + IxCryptoAccPkeEauOperation operation,
  14630. + IxCryptoAccPkeEauOpResult *pResult,
  14631. + BOOL carryOrBorrow,
  14632. + IxCryptoAccStatus status)
  14633. +{
  14634. + struct ixp_pkq *q, *tmp;
  14635. + unsigned long flags;
  14636. +
  14637. + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
  14638. + carryOrBorrow, status);
  14639. +
  14640. + /* handle a completed request */
  14641. + if (pResult) {
  14642. + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
  14643. + q = ixp_pk_cur;
  14644. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14645. + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
  14646. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  14647. + } else {
  14648. + /* copy out the result */
  14649. + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
  14650. + &q->pkq_result, q->pkq_obuf))
  14651. + q->pkq_krp->krp_status = ERANGE;
  14652. + }
  14653. + crypto_kdone(q->pkq_krp);
  14654. + kfree(q);
  14655. + ixp_pk_cur = NULL;
  14656. + } else
  14657. + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
  14658. + }
  14659. +
  14660. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  14661. + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
  14662. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14663. + return;
  14664. + }
  14665. +
  14666. + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
  14667. +
  14668. + list_del(&q->pkq_list);
  14669. + ixp_pk_cur = q;
  14670. +
  14671. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14672. +
  14673. + status = ixCryptoAccPkeEauPerform(
  14674. + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
  14675. + &q->pkq_op,
  14676. + ixp_kperform_cb,
  14677. + &q->pkq_result);
  14678. +
  14679. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14680. + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
  14681. + return; /* callback will return here for callback */
  14682. + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
  14683. + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
  14684. + } else {
  14685. + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
  14686. + __FUNCTION__, status);
  14687. + }
  14688. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  14689. + crypto_kdone(q->pkq_krp);
  14690. + kfree(q);
  14691. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  14692. + }
  14693. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14694. +}
  14695. +
  14696. +
  14697. +static int
  14698. +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
  14699. +{
  14700. + struct ixp_pkq *q;
  14701. + int rc = 0;
  14702. + unsigned long flags;
  14703. +
  14704. + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
  14705. + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
  14706. + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
  14707. + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
  14708. + krp->krp_param[IXP_PARAM_RES].crp_nbits);
  14709. +
  14710. +
  14711. + if (krp->krp_op != CRK_MOD_EXP) {
  14712. + krp->krp_status = EOPNOTSUPP;
  14713. + goto err;
  14714. + }
  14715. +
  14716. + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  14717. + if (q == NULL) {
  14718. + krp->krp_status = ENOMEM;
  14719. + goto err;
  14720. + }
  14721. +
  14722. + /*
  14723. + * The PKE engine does not appear to zero the output buffer
  14724. + * appropriately, so we need to do it all here.
  14725. + */
  14726. + memset(q, 0, sizeof(*q));
  14727. +
  14728. + q->pkq_krp = krp;
  14729. + INIT_LIST_HEAD(&q->pkq_list);
  14730. +
  14731. + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
  14732. + q->pkq_ibuf0))
  14733. + rc = 1;
  14734. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
  14735. + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
  14736. + rc = 2;
  14737. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
  14738. + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
  14739. + rc = 3;
  14740. +
  14741. + if (rc) {
  14742. + kfree(q);
  14743. + krp->krp_status = ERANGE;
  14744. + goto err;
  14745. + }
  14746. +
  14747. + q->pkq_result.pData = q->pkq_obuf;
  14748. + q->pkq_result.dataLen =
  14749. + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
  14750. +
  14751. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  14752. + list_add_tail(&q->pkq_list, &ixp_pkq);
  14753. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  14754. +
  14755. + if (!ixp_pk_cur)
  14756. + ixp_kperform_cb(0, NULL, 0, 0);
  14757. + return (0);
  14758. +
  14759. +err:
  14760. + crypto_kdone(krp);
  14761. + return (0);
  14762. +}
  14763. +
  14764. +
  14765. +
  14766. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14767. +/*
  14768. + * We run the random number generator output through SHA so that it
  14769. + * is FIPS compliant.
  14770. + */
  14771. +
  14772. +static volatile int sha_done = 0;
  14773. +static unsigned char sha_digest[20];
  14774. +
  14775. +static void
  14776. +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
  14777. +{
  14778. + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
  14779. + if (sha_digest != digest)
  14780. + printk("digest error\n");
  14781. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  14782. + sha_done = 1;
  14783. + else
  14784. + sha_done = -status;
  14785. +}
  14786. +
  14787. +static int
  14788. +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
  14789. +{
  14790. + IxCryptoAccStatus status;
  14791. + int i, n, rc;
  14792. +
  14793. + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
  14794. + memset(buf, 0, maxwords * sizeof(*buf));
  14795. + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
  14796. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14797. + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
  14798. + __FUNCTION__, status);
  14799. + return 0;
  14800. + }
  14801. +
  14802. + /*
  14803. + * run the random data through SHA to make it look more random
  14804. + */
  14805. +
  14806. + n = sizeof(sha_digest); /* process digest bytes at a time */
  14807. +
  14808. + rc = 0;
  14809. + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
  14810. + if ((maxwords - i) * sizeof(*buf) < n)
  14811. + n = (maxwords - i) * sizeof(*buf);
  14812. + sha_done = 0;
  14813. + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
  14814. + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
  14815. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  14816. + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
  14817. + return -EIO;
  14818. + }
  14819. + while (!sha_done)
  14820. + schedule();
  14821. + if (sha_done < 0) {
  14822. + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
  14823. + return 0;
  14824. + }
  14825. + memcpy(&buf[i], sha_digest, n);
  14826. + rc += n / sizeof(*buf);;
  14827. + }
  14828. +
  14829. + return rc;
  14830. +}
  14831. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  14832. +
  14833. +#endif /* __ixp46X */
  14834. +
  14835. +
  14836. +
  14837. +/*
  14838. + * our driver startup and shutdown routines
  14839. + */
  14840. +
  14841. +static int
  14842. +ixp_init(void)
  14843. +{
  14844. + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
  14845. +
  14846. + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
  14847. + printk("ixCryptoAccInit failed, assuming already initialised!\n");
  14848. +
  14849. + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
  14850. + SLAB_HWCACHE_ALIGN, NULL
  14851. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  14852. + , NULL
  14853. +#endif
  14854. + );
  14855. + if (!qcache) {
  14856. + printk("failed to create Qcache\n");
  14857. + return -ENOENT;
  14858. + }
  14859. +
  14860. + memset(&ixpdev, 0, sizeof(ixpdev));
  14861. + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
  14862. +
  14863. + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
  14864. + CRYPTOCAP_F_HARDWARE);
  14865. + if (ixp_id < 0)
  14866. + panic("IXP/OCF crypto device cannot initialize!");
  14867. +
  14868. +#define REGISTER(alg) \
  14869. + crypto_register(ixp_id,alg,0,0)
  14870. +
  14871. + REGISTER(CRYPTO_DES_CBC);
  14872. + REGISTER(CRYPTO_3DES_CBC);
  14873. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  14874. +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
  14875. + REGISTER(CRYPTO_MD5);
  14876. + REGISTER(CRYPTO_SHA1);
  14877. +#endif
  14878. + REGISTER(CRYPTO_MD5_HMAC);
  14879. + REGISTER(CRYPTO_SHA1_HMAC);
  14880. +#undef REGISTER
  14881. +
  14882. +#ifdef __ixp46X
  14883. + spin_lock_init(&ixp_pkq_lock);
  14884. + /*
  14885. + * we do not enable the go fast options here as they can potentially
  14886. + * allow timing based attacks
  14887. + *
  14888. + * http://www.openssl.org/news/secadv_20030219.txt
  14889. + */
  14890. + ixCryptoAccPkeEauExpConfig(0, 0);
  14891. + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
  14892. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14893. + crypto_rregister(ixp_id, ixp_read_random, NULL);
  14894. +#endif
  14895. +#endif
  14896. +
  14897. + return 0;
  14898. +}
  14899. +
  14900. +static void
  14901. +ixp_exit(void)
  14902. +{
  14903. + dprintk("%s()\n", __FUNCTION__);
  14904. + crypto_unregister_all(ixp_id);
  14905. + ixp_id = -1;
  14906. + kmem_cache_destroy(qcache);
  14907. + qcache = NULL;
  14908. +}
  14909. +
  14910. +module_init(ixp_init);
  14911. +module_exit(ixp_exit);
  14912. +
  14913. +MODULE_LICENSE("Dual BSD/GPL");
  14914. +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
  14915. +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
  14916. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ocf-bench.c linux-2.6.29.1/crypto/ocf/ocf-bench.c
  14917. --- linux-2.6.29.1.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
  14918. +++ linux-2.6.29.1/crypto/ocf/ocf-bench.c 2009-04-20 20:01:21.548558198 +0200
  14919. @@ -0,0 +1,436 @@
  14920. +/*
  14921. + * A loadable module that benchmarks the OCF crypto speed from kernel space.
  14922. + *
  14923. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
  14924. + *
  14925. + * LICENSE TERMS
  14926. + *
  14927. + * The free distribution and use of this software in both source and binary
  14928. + * form is allowed (with or without changes) provided that:
  14929. + *
  14930. + * 1. distributions of this source code include the above copyright
  14931. + * notice, this list of conditions and the following disclaimer;
  14932. + *
  14933. + * 2. distributions in binary form include the above copyright
  14934. + * notice, this list of conditions and the following disclaimer
  14935. + * in the documentation and/or other associated materials;
  14936. + *
  14937. + * 3. the copyright holder's name is not used to endorse products
  14938. + * built using this software without specific written permission.
  14939. + *
  14940. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  14941. + * may be distributed under the terms of the GNU General Public License (GPL),
  14942. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  14943. + *
  14944. + * DISCLAIMER
  14945. + *
  14946. + * This software is provided 'as is' with no explicit or implied warranties
  14947. + * in respect of its properties, including, but not limited to, correctness
  14948. + * and/or fitness for purpose.
  14949. + */
  14950. +
  14951. +
  14952. +#ifndef AUTOCONF_INCLUDED
  14953. +#include <linux/config.h>
  14954. +#endif
  14955. +#include <linux/module.h>
  14956. +#include <linux/init.h>
  14957. +#include <linux/list.h>
  14958. +#include <linux/slab.h>
  14959. +#include <linux/wait.h>
  14960. +#include <linux/sched.h>
  14961. +#include <linux/spinlock.h>
  14962. +#include <linux/version.h>
  14963. +#include <linux/interrupt.h>
  14964. +#include <cryptodev.h>
  14965. +
  14966. +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
  14967. +#define BENCH_IXP_ACCESS_LIB 1
  14968. +#endif
  14969. +#ifdef BENCH_IXP_ACCESS_LIB
  14970. +#include <IxTypes.h>
  14971. +#include <IxOsBuffMgt.h>
  14972. +#include <IxNpeDl.h>
  14973. +#include <IxCryptoAcc.h>
  14974. +#include <IxQMgr.h>
  14975. +#include <IxOsServices.h>
  14976. +#include <IxOsCacheMMU.h>
  14977. +#endif
  14978. +
  14979. +/*
  14980. + * support for access lib version 1.4
  14981. + */
  14982. +#ifndef IX_MBUF_PRIV
  14983. +#define IX_MBUF_PRIV(x) ((x)->priv)
  14984. +#endif
  14985. +
  14986. +/*
  14987. + * the number of simultaneously active requests
  14988. + */
  14989. +static int request_q_len = 20;
  14990. +module_param(request_q_len, int, 0);
  14991. +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
  14992. +/*
  14993. + * how many requests we want to have processed
  14994. + */
  14995. +static int request_num = 1024;
  14996. +module_param(request_num, int, 0);
  14997. +MODULE_PARM_DESC(request_num, "run for at least this many requests");
  14998. +/*
  14999. + * the size of each request
  15000. + */
  15001. +static int request_size = 1500;
  15002. +module_param(request_size, int, 0);
  15003. +MODULE_PARM_DESC(request_size, "size of each request");
  15004. +
  15005. +/*
  15006. + * a structure for each request
  15007. + */
  15008. +typedef struct {
  15009. + struct work_struct work;
  15010. +#ifdef BENCH_IXP_ACCESS_LIB
  15011. + IX_MBUF mbuf;
  15012. +#endif
  15013. + unsigned char *buffer;
  15014. +} request_t;
  15015. +
  15016. +static request_t *requests;
  15017. +
  15018. +static int outstanding;
  15019. +static int total;
  15020. +
  15021. +/*************************************************************************/
  15022. +/*
  15023. + * OCF benchmark routines
  15024. + */
  15025. +
  15026. +static uint64_t ocf_cryptoid;
  15027. +static int ocf_init(void);
  15028. +static int ocf_cb(struct cryptop *crp);
  15029. +static void ocf_request(void *arg);
  15030. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15031. +static void ocf_request_wq(struct work_struct *work);
  15032. +#endif
  15033. +
  15034. +static int
  15035. +ocf_init(void)
  15036. +{
  15037. + int error;
  15038. + struct cryptoini crie, cria;
  15039. + struct cryptodesc crda, crde;
  15040. +
  15041. + memset(&crie, 0, sizeof(crie));
  15042. + memset(&cria, 0, sizeof(cria));
  15043. + memset(&crde, 0, sizeof(crde));
  15044. + memset(&crda, 0, sizeof(crda));
  15045. +
  15046. + cria.cri_alg = CRYPTO_SHA1_HMAC;
  15047. + cria.cri_klen = 20 * 8;
  15048. + cria.cri_key = "0123456789abcdefghij";
  15049. +
  15050. + crie.cri_alg = CRYPTO_3DES_CBC;
  15051. + crie.cri_klen = 24 * 8;
  15052. + crie.cri_key = "0123456789abcdefghijklmn";
  15053. +
  15054. + crie.cri_next = &cria;
  15055. +
  15056. + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
  15057. + if (error) {
  15058. + printk("crypto_newsession failed %d\n", error);
  15059. + return -1;
  15060. + }
  15061. + return 0;
  15062. +}
  15063. +
  15064. +static int
  15065. +ocf_cb(struct cryptop *crp)
  15066. +{
  15067. + request_t *r = (request_t *) crp->crp_opaque;
  15068. +
  15069. + if (crp->crp_etype)
  15070. + printk("Error in OCF processing: %d\n", crp->crp_etype);
  15071. + total++;
  15072. + crypto_freereq(crp);
  15073. + crp = NULL;
  15074. +
  15075. + if (total > request_num) {
  15076. + outstanding--;
  15077. + return 0;
  15078. + }
  15079. +
  15080. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15081. + INIT_WORK(&r->work, ocf_request_wq);
  15082. +#else
  15083. + INIT_WORK(&r->work, ocf_request, r);
  15084. +#endif
  15085. + schedule_work(&r->work);
  15086. + return 0;
  15087. +}
  15088. +
  15089. +
  15090. +static void
  15091. +ocf_request(void *arg)
  15092. +{
  15093. + request_t *r = arg;
  15094. + struct cryptop *crp = crypto_getreq(2);
  15095. + struct cryptodesc *crde, *crda;
  15096. +
  15097. + if (!crp) {
  15098. + outstanding--;
  15099. + return;
  15100. + }
  15101. +
  15102. + crde = crp->crp_desc;
  15103. + crda = crde->crd_next;
  15104. +
  15105. + crda->crd_skip = 0;
  15106. + crda->crd_flags = 0;
  15107. + crda->crd_len = request_size;
  15108. + crda->crd_inject = request_size;
  15109. + crda->crd_alg = CRYPTO_SHA1_HMAC;
  15110. + crda->crd_key = "0123456789abcdefghij";
  15111. + crda->crd_klen = 20 * 8;
  15112. +
  15113. + crde->crd_skip = 0;
  15114. + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
  15115. + crde->crd_len = request_size;
  15116. + crde->crd_inject = request_size;
  15117. + crde->crd_alg = CRYPTO_3DES_CBC;
  15118. + crde->crd_key = "0123456789abcdefghijklmn";
  15119. + crde->crd_klen = 24 * 8;
  15120. +
  15121. + crp->crp_ilen = request_size + 64;
  15122. + crp->crp_flags = CRYPTO_F_CBIMM;
  15123. + crp->crp_buf = (caddr_t) r->buffer;
  15124. + crp->crp_callback = ocf_cb;
  15125. + crp->crp_sid = ocf_cryptoid;
  15126. + crp->crp_opaque = (caddr_t) r;
  15127. + crypto_dispatch(crp);
  15128. +}
  15129. +
  15130. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15131. +static void
  15132. +ocf_request_wq(struct work_struct *work)
  15133. +{
  15134. + request_t *r = container_of(work, request_t, work);
  15135. + ocf_request(r);
  15136. +}
  15137. +#endif
  15138. +
  15139. +/*************************************************************************/
  15140. +#ifdef BENCH_IXP_ACCESS_LIB
  15141. +/*************************************************************************/
  15142. +/*
  15143. + * CryptoAcc benchmark routines
  15144. + */
  15145. +
  15146. +static IxCryptoAccCtx ixp_ctx;
  15147. +static UINT32 ixp_ctx_id;
  15148. +static IX_MBUF ixp_pri;
  15149. +static IX_MBUF ixp_sec;
  15150. +static int ixp_registered = 0;
  15151. +
  15152. +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
  15153. + IxCryptoAccStatus status);
  15154. +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
  15155. + IxCryptoAccStatus status);
  15156. +static void ixp_request(void *arg);
  15157. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15158. +static void ixp_request_wq(struct work_struct *work);
  15159. +#endif
  15160. +
  15161. +static int
  15162. +ixp_init(void)
  15163. +{
  15164. + IxCryptoAccStatus status;
  15165. +
  15166. + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  15167. + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  15168. + ixp_ctx.cipherCtx.cipherKeyLen = 24;
  15169. + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  15170. + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
  15171. + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
  15172. +
  15173. + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  15174. + ixp_ctx.authCtx.authDigestLen = 12;
  15175. + ixp_ctx.authCtx.aadLen = 0;
  15176. + ixp_ctx.authCtx.authKeyLen = 20;
  15177. + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
  15178. +
  15179. + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  15180. + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
  15181. +
  15182. + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
  15183. + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  15184. + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
  15185. + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  15186. +
  15187. + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
  15188. + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
  15189. +
  15190. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
  15191. + while (!ixp_registered)
  15192. + schedule();
  15193. + return ixp_registered < 0 ? -1 : 0;
  15194. + }
  15195. +
  15196. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  15197. + return -1;
  15198. +}
  15199. +
  15200. +static void
  15201. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  15202. +{
  15203. + if (bufp) {
  15204. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  15205. + kfree(IX_MBUF_MDATA(bufp));
  15206. + IX_MBUF_MDATA(bufp) = NULL;
  15207. + }
  15208. +
  15209. + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
  15210. + return;
  15211. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  15212. + ixp_registered = 1;
  15213. + else
  15214. + ixp_registered = -1;
  15215. +}
  15216. +
  15217. +static void
  15218. +ixp_perform_cb(
  15219. + UINT32 ctx_id,
  15220. + IX_MBUF *sbufp,
  15221. + IX_MBUF *dbufp,
  15222. + IxCryptoAccStatus status)
  15223. +{
  15224. + request_t *r = NULL;
  15225. +
  15226. + total++;
  15227. + if (total > request_num) {
  15228. + outstanding--;
  15229. + return;
  15230. + }
  15231. +
  15232. + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
  15233. + printk("crappo %p %p\n", sbufp, r);
  15234. + outstanding--;
  15235. + return;
  15236. + }
  15237. +
  15238. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15239. + INIT_WORK(&r->work, ixp_request_wq);
  15240. +#else
  15241. + INIT_WORK(&r->work, ixp_request, r);
  15242. +#endif
  15243. + schedule_work(&r->work);
  15244. +}
  15245. +
  15246. +static void
  15247. +ixp_request(void *arg)
  15248. +{
  15249. + request_t *r = arg;
  15250. + IxCryptoAccStatus status;
  15251. +
  15252. + memset(&r->mbuf, 0, sizeof(r->mbuf));
  15253. + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
  15254. + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
  15255. + IX_MBUF_PRIV(&r->mbuf) = r;
  15256. + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
  15257. + 0, request_size, 0, request_size, request_size, r->buffer);
  15258. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  15259. + printk("status1 = %d\n", status);
  15260. + outstanding--;
  15261. + return;
  15262. + }
  15263. + return;
  15264. +}
  15265. +
  15266. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  15267. +static void
  15268. +ixp_request_wq(struct work_struct *work)
  15269. +{
  15270. + request_t *r = container_of(work, request_t, work);
  15271. + ixp_request(r);
  15272. +}
  15273. +#endif
  15274. +
  15275. +/*************************************************************************/
  15276. +#endif /* BENCH_IXP_ACCESS_LIB */
  15277. +/*************************************************************************/
  15278. +
  15279. +int
  15280. +ocfbench_init(void)
  15281. +{
  15282. + int i, jstart, jstop;
  15283. +
  15284. + printk("Crypto Speed tests\n");
  15285. +
  15286. + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
  15287. + if (!requests) {
  15288. + printk("malloc failed\n");
  15289. + return -EINVAL;
  15290. + }
  15291. +
  15292. + for (i = 0; i < request_q_len; i++) {
  15293. + /* +64 for return data */
  15294. + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
  15295. + if (!requests[i].buffer) {
  15296. + printk("malloc failed\n");
  15297. + return -EINVAL;
  15298. + }
  15299. + memset(requests[i].buffer, '0' + i, request_size + 128);
  15300. + }
  15301. +
  15302. + /*
  15303. + * OCF benchmark
  15304. + */
  15305. + printk("OCF: testing ...\n");
  15306. + ocf_init();
  15307. + total = outstanding = 0;
  15308. + jstart = jiffies;
  15309. + for (i = 0; i < request_q_len; i++) {
  15310. + outstanding++;
  15311. + ocf_request(&requests[i]);
  15312. + }
  15313. + while (outstanding > 0)
  15314. + schedule();
  15315. + jstop = jiffies;
  15316. +
  15317. + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
  15318. + jstop - jstart);
  15319. +
  15320. +#ifdef BENCH_IXP_ACCESS_LIB
  15321. + /*
  15322. + * IXP benchmark
  15323. + */
  15324. + printk("IXP: testing ...\n");
  15325. + ixp_init();
  15326. + total = outstanding = 0;
  15327. + jstart = jiffies;
  15328. + for (i = 0; i < request_q_len; i++) {
  15329. + outstanding++;
  15330. + ixp_request(&requests[i]);
  15331. + }
  15332. + while (outstanding > 0)
  15333. + schedule();
  15334. + jstop = jiffies;
  15335. +
  15336. + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
  15337. + jstop - jstart);
  15338. +#endif /* BENCH_IXP_ACCESS_LIB */
  15339. +
  15340. + for (i = 0; i < request_q_len; i++)
  15341. + kfree(requests[i].buffer);
  15342. + kfree(requests);
  15343. + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
  15344. +}
  15345. +
  15346. +static void __exit ocfbench_exit(void)
  15347. +{
  15348. +}
  15349. +
  15350. +module_init(ocfbench_init);
  15351. +module_exit(ocfbench_exit);
  15352. +
  15353. +MODULE_LICENSE("BSD");
  15354. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  15355. +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
  15356. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ocf-compat.h linux-2.6.29.1/crypto/ocf/ocf-compat.h
  15357. --- linux-2.6.29.1.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
  15358. +++ linux-2.6.29.1/crypto/ocf/ocf-compat.h 2009-04-20 20:01:21.552559545 +0200
  15359. @@ -0,0 +1,270 @@
  15360. +#ifndef _BSD_COMPAT_H_
  15361. +#define _BSD_COMPAT_H_ 1
  15362. +/****************************************************************************/
  15363. +/*
  15364. + * Provide compat routines for older linux kernels and BSD kernels
  15365. + *
  15366. + * Written by David McCullough <david_mccullough@securecomputing.com>
  15367. + * Copyright (C) 2007 David McCullough <david_mccullough@securecomputing.com>
  15368. + *
  15369. + * LICENSE TERMS
  15370. + *
  15371. + * The free distribution and use of this software in both source and binary
  15372. + * form is allowed (with or without changes) provided that:
  15373. + *
  15374. + * 1. distributions of this source code include the above copyright
  15375. + * notice, this list of conditions and the following disclaimer;
  15376. + *
  15377. + * 2. distributions in binary form include the above copyright
  15378. + * notice, this list of conditions and the following disclaimer
  15379. + * in the documentation and/or other associated materials;
  15380. + *
  15381. + * 3. the copyright holder's name is not used to endorse products
  15382. + * built using this software without specific written permission.
  15383. + *
  15384. + * ALTERNATIVELY, provided that this notice is retained in full, this file
  15385. + * may be distributed under the terms of the GNU General Public License (GPL),
  15386. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  15387. + *
  15388. + * DISCLAIMER
  15389. + *
  15390. + * This software is provided 'as is' with no explicit or implied warranties
  15391. + * in respect of its properties, including, but not limited to, correctness
  15392. + * and/or fitness for purpose.
  15393. + */
  15394. +/****************************************************************************/
  15395. +#ifdef __KERNEL__
  15396. +/*
  15397. + * fake some BSD driver interface stuff specifically for OCF use
  15398. + */
  15399. +
  15400. +typedef struct ocf_device *device_t;
  15401. +
  15402. +typedef struct {
  15403. + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
  15404. + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
  15405. + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
  15406. + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
  15407. +} device_method_t;
  15408. +#define DEVMETHOD(id, func) id: func
  15409. +
  15410. +struct ocf_device {
  15411. + char name[32]; /* the driver name */
  15412. + char nameunit[32]; /* the driver name + HW instance */
  15413. + int unit;
  15414. + device_method_t methods;
  15415. + void *softc;
  15416. +};
  15417. +
  15418. +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
  15419. + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
  15420. +#define CRYPTODEV_FREESESSION(dev, sid) \
  15421. + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
  15422. +#define CRYPTODEV_PROCESS(dev, crp, hint) \
  15423. + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
  15424. +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
  15425. + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
  15426. +
  15427. +#define device_get_name(dev) ((dev)->name)
  15428. +#define device_get_nameunit(dev) ((dev)->nameunit)
  15429. +#define device_get_unit(dev) ((dev)->unit)
  15430. +#define device_get_softc(dev) ((dev)->softc)
  15431. +
  15432. +#define softc_device_decl \
  15433. + struct ocf_device _device; \
  15434. + device_t
  15435. +
  15436. +#define softc_device_init(_sc, _name, _unit, _methods) \
  15437. + if (1) {\
  15438. + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
  15439. + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
  15440. + (_sc)->_device.unit = _unit; \
  15441. + (_sc)->_device.methods = _methods; \
  15442. + (_sc)->_device.softc = (void *) _sc; \
  15443. + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
  15444. + } else
  15445. +
  15446. +#define softc_get_device(_sc) (&(_sc)->_device)
  15447. +
  15448. +/*
  15449. + * iomem support for 2.4 and 2.6 kernels
  15450. + */
  15451. +#include <linux/version.h>
  15452. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  15453. +#define ocf_iomem_t unsigned long
  15454. +
  15455. +/*
  15456. + * implement simple workqueue like support for older kernels
  15457. + */
  15458. +
  15459. +#include <linux/tqueue.h>
  15460. +
  15461. +#define work_struct tq_struct
  15462. +
  15463. +#define INIT_WORK(wp, fp, ap) \
  15464. + do { \
  15465. + (wp)->sync = 0; \
  15466. + (wp)->routine = (fp); \
  15467. + (wp)->data = (ap); \
  15468. + } while (0)
  15469. +
  15470. +#define schedule_work(wp) \
  15471. + do { \
  15472. + queue_task((wp), &tq_immediate); \
  15473. + mark_bh(IMMEDIATE_BH); \
  15474. + } while (0)
  15475. +
  15476. +#define flush_scheduled_work() run_task_queue(&tq_immediate)
  15477. +
  15478. +#else
  15479. +#define ocf_iomem_t void __iomem *
  15480. +
  15481. +#include <linux/workqueue.h>
  15482. +
  15483. +#endif
  15484. +
  15485. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
  15486. +#include <linux/fdtable.h>
  15487. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
  15488. +#define files_fdtable(files) (files)
  15489. +#endif
  15490. +
  15491. +#ifdef MODULE_PARM
  15492. +#undef module_param /* just in case */
  15493. +#define module_param(a,b,c) MODULE_PARM(a,"i")
  15494. +#endif
  15495. +
  15496. +#define bzero(s,l) memset(s,0,l)
  15497. +#define bcopy(s,d,l) memcpy(d,s,l)
  15498. +#define bcmp(x, y, l) memcmp(x,y,l)
  15499. +
  15500. +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  15501. +
  15502. +#define device_printf(dev, a...) ({ \
  15503. + printk("%s: ", device_get_nameunit(dev)); printk(a); \
  15504. + })
  15505. +
  15506. +#undef printf
  15507. +#define printf(fmt...) printk(fmt)
  15508. +
  15509. +#define KASSERT(c,p) if (!(c)) { printk p ; } else
  15510. +
  15511. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  15512. +#define ocf_daemonize(str) \
  15513. + daemonize(); \
  15514. + spin_lock_irq(&current->sigmask_lock); \
  15515. + sigemptyset(&current->blocked); \
  15516. + recalc_sigpending(current); \
  15517. + spin_unlock_irq(&current->sigmask_lock); \
  15518. + sprintf(current->comm, str);
  15519. +#else
  15520. +#define ocf_daemonize(str) daemonize(str);
  15521. +#endif
  15522. +
  15523. +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
  15524. +#define TAILQ_EMPTY(q) list_empty(q)
  15525. +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
  15526. +
  15527. +#define read_random(p,l) get_random_bytes(p,l)
  15528. +
  15529. +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
  15530. +#define strtoul simple_strtoul
  15531. +
  15532. +#define pci_get_vendor(dev) ((dev)->vendor)
  15533. +#define pci_get_device(dev) ((dev)->device)
  15534. +
  15535. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  15536. +#define pci_set_consistent_dma_mask(dev, mask) (0)
  15537. +#endif
  15538. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  15539. +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
  15540. +#endif
  15541. +
  15542. +#ifndef DMA_32BIT_MASK
  15543. +#define DMA_32BIT_MASK 0x00000000ffffffffULL
  15544. +#endif
  15545. +
  15546. +#define htole32(x) cpu_to_le32(x)
  15547. +#define htobe32(x) cpu_to_be32(x)
  15548. +#define htole16(x) cpu_to_le16(x)
  15549. +#define htobe16(x) cpu_to_be16(x)
  15550. +
  15551. +/* older kernels don't have these */
  15552. +
  15553. +#ifndef IRQ_NONE
  15554. +#define IRQ_NONE
  15555. +#define IRQ_HANDLED
  15556. +#define irqreturn_t void
  15557. +#endif
  15558. +#ifndef IRQF_SHARED
  15559. +#define IRQF_SHARED SA_SHIRQ
  15560. +#endif
  15561. +
  15562. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  15563. +# define strlcpy(dest,src,len) \
  15564. + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
  15565. +#endif
  15566. +
  15567. +#ifndef MAX_ERRNO
  15568. +#define MAX_ERRNO 4095
  15569. +#endif
  15570. +#ifndef IS_ERR_VALUE
  15571. +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
  15572. +#endif
  15573. +
  15574. +/*
  15575. + * common debug for all
  15576. + */
  15577. +#if 1
  15578. +#define dprintk(a...) do { if (debug) printk(a); } while(0)
  15579. +#else
  15580. +#define dprintk(a...)
  15581. +#endif
  15582. +
  15583. +#ifndef SLAB_ATOMIC
  15584. +/* Changed in 2.6.20, must use GFP_ATOMIC now */
  15585. +#define SLAB_ATOMIC GFP_ATOMIC
  15586. +#endif
  15587. +
  15588. +/*
  15589. + * need some additional support for older kernels */
  15590. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
  15591. +#define pci_register_driver_compat(driver, rc) \
  15592. + do { \
  15593. + if ((rc) > 0) { \
  15594. + (rc) = 0; \
  15595. + } else if (rc == 0) { \
  15596. + (rc) = -ENODEV; \
  15597. + } else { \
  15598. + pci_unregister_driver(driver); \
  15599. + } \
  15600. + } while (0)
  15601. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  15602. +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
  15603. +#else
  15604. +#define pci_register_driver_compat(driver,rc)
  15605. +#endif
  15606. +
  15607. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  15608. +
  15609. +#include <asm/scatterlist.h>
  15610. +
  15611. +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
  15612. + unsigned int len, unsigned int offset)
  15613. +{
  15614. + sg->page = page;
  15615. + sg->offset = offset;
  15616. + sg->length = len;
  15617. +}
  15618. +
  15619. +static inline void *sg_virt(struct scatterlist *sg)
  15620. +{
  15621. + return page_address(sg->page) + sg->offset;
  15622. +}
  15623. +
  15624. +#endif
  15625. +
  15626. +#endif /* __KERNEL__ */
  15627. +
  15628. +/****************************************************************************/
  15629. +#endif /* _BSD_COMPAT_H_ */
  15630. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ocfnull/Makefile linux-2.6.29.1/crypto/ocf/ocfnull/Makefile
  15631. --- linux-2.6.29.1.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
  15632. +++ linux-2.6.29.1/crypto/ocf/ocfnull/Makefile 2009-04-20 20:01:21.552559545 +0200
  15633. @@ -0,0 +1,12 @@
  15634. +# for SGlinux builds
  15635. +-include $(ROOTDIR)/modules/.config
  15636. +
  15637. +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
  15638. +
  15639. +obj ?= .
  15640. +EXTRA_CFLAGS += -I$(obj)/..
  15641. +
  15642. +ifdef TOPDIR
  15643. +-include $(TOPDIR)/Rules.make
  15644. +endif
  15645. +
  15646. diff -Nur linux-2.6.29.1.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.29.1/crypto/ocf/ocfnull/ocfnull.c
  15647. --- linux-2.6.29.1.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
  15648. +++ linux-2.6.29.1/crypto/ocf/ocfnull/ocfnull.c 2009-04-20 20:01:21.552559545 +0200
  15649. @@ -0,0 +1,203 @@
  15650. +/*
  15651. + * An OCF module for determining the cost of crypto versus the cost of
  15652. + * IPSec processing outside of OCF. This modules gives us the effect of
  15653. + * zero cost encryption, of course you will need to run it at both ends
  15654. + * since it does no crypto at all.
  15655. + *
  15656. + * Written by David McCullough <david_mccullough@securecomputing.com>
  15657. + * Copyright (C) 2006-2007 David McCullough
  15658. + *
  15659. + * LICENSE TERMS
  15660. + *
  15661. + * The free distribution and use of this software in both source and binary
  15662. + * form is allowed (with or without changes) provided that:
  15663. + *
  15664. + * 1. distributions of this source code include the above copyright
  15665. + * notice, this list of conditions and the following disclaimer;
  15666. + *
  15667. + * 2. distributions in binary form include the above copyright
  15668. + * notice, this list of conditions and the following disclaimer
  15669. + * in the documentation and/or other associated materials;
  15670. + *
  15671. + * 3. the copyright holder's name is not used to endorse products
  15672. + * built using this software without specific written permission.
  15673. + *
  15674. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  15675. + * may be distributed under the terms of the GNU General Public License (GPL),
  15676. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  15677. + *
  15678. + * DISCLAIMER
  15679. + *
  15680. + * This software is provided 'as is' with no explicit or implied warranties
  15681. + * in respect of its properties, including, but not limited to, correctness
  15682. + * and/or fitness for purpose.
  15683. + */
  15684. +
  15685. +#ifndef AUTOCONF_INCLUDED
  15686. +#include <linux/config.h>
  15687. +#endif
  15688. +#include <linux/module.h>
  15689. +#include <linux/init.h>
  15690. +#include <linux/list.h>
  15691. +#include <linux/slab.h>
  15692. +#include <linux/sched.h>
  15693. +#include <linux/wait.h>
  15694. +#include <linux/crypto.h>
  15695. +#include <linux/interrupt.h>
  15696. +
  15697. +#include <cryptodev.h>
  15698. +#include <uio.h>
  15699. +
  15700. +static int32_t null_id = -1;
  15701. +static u_int32_t null_sesnum = 0;
  15702. +
  15703. +static int null_process(device_t, struct cryptop *, int);
  15704. +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
  15705. +static int null_freesession(device_t, u_int64_t);
  15706. +
  15707. +#define debug ocfnull_debug
  15708. +int ocfnull_debug = 0;
  15709. +module_param(ocfnull_debug, int, 0644);
  15710. +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
  15711. +
  15712. +/*
  15713. + * dummy device structure
  15714. + */
  15715. +
  15716. +static struct {
  15717. + softc_device_decl sc_dev;
  15718. +} nulldev;
  15719. +
  15720. +static device_method_t null_methods = {
  15721. + /* crypto device methods */
  15722. + DEVMETHOD(cryptodev_newsession, null_newsession),
  15723. + DEVMETHOD(cryptodev_freesession,null_freesession),
  15724. + DEVMETHOD(cryptodev_process, null_process),
  15725. +};
  15726. +
  15727. +/*
  15728. + * Generate a new software session.
  15729. + */
  15730. +static int
  15731. +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
  15732. +{
  15733. + dprintk("%s()\n", __FUNCTION__);
  15734. + if (sid == NULL || cri == NULL) {
  15735. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  15736. + return EINVAL;
  15737. + }
  15738. +
  15739. + if (null_sesnum == 0)
  15740. + null_sesnum++;
  15741. + *sid = null_sesnum++;
  15742. + return 0;
  15743. +}
  15744. +
  15745. +
  15746. +/*
  15747. + * Free a session.
  15748. + */
  15749. +static int
  15750. +null_freesession(device_t arg, u_int64_t tid)
  15751. +{
  15752. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  15753. +
  15754. + dprintk("%s()\n", __FUNCTION__);
  15755. + if (sid > null_sesnum) {
  15756. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  15757. + return EINVAL;
  15758. + }
  15759. +
  15760. + /* Silently accept and return */
  15761. + if (sid == 0)
  15762. + return 0;
  15763. + return 0;
  15764. +}
  15765. +
  15766. +
  15767. +/*
  15768. + * Process a request.
  15769. + */
  15770. +static int
  15771. +null_process(device_t arg, struct cryptop *crp, int hint)
  15772. +{
  15773. + unsigned int lid;
  15774. +
  15775. + dprintk("%s()\n", __FUNCTION__);
  15776. +
  15777. + /* Sanity check */
  15778. + if (crp == NULL) {
  15779. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  15780. + return EINVAL;
  15781. + }
  15782. +
  15783. + crp->crp_etype = 0;
  15784. +
  15785. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  15786. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  15787. + crp->crp_etype = EINVAL;
  15788. + goto done;
  15789. + }
  15790. +
  15791. + /*
  15792. + * find the session we are using
  15793. + */
  15794. +
  15795. + lid = crp->crp_sid & 0xffffffff;
  15796. + if (lid >= null_sesnum || lid == 0) {
  15797. + crp->crp_etype = ENOENT;
  15798. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  15799. + goto done;
  15800. + }
  15801. +
  15802. +done:
  15803. + crypto_done(crp);
  15804. + return 0;
  15805. +}
  15806. +
  15807. +
  15808. +/*
  15809. + * our driver startup and shutdown routines
  15810. + */
  15811. +
  15812. +static int
  15813. +null_init(void)
  15814. +{
  15815. + dprintk("%s(%p)\n", __FUNCTION__, null_init);
  15816. +
  15817. + memset(&nulldev, 0, sizeof(nulldev));
  15818. + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
  15819. +
  15820. + null_id = crypto_get_driverid(softc_get_device(&nulldev),
  15821. + CRYPTOCAP_F_HARDWARE);
  15822. + if (null_id < 0)
  15823. + panic("ocfnull: crypto device cannot initialize!");
  15824. +
  15825. +#define REGISTER(alg) \
  15826. + crypto_register(null_id,alg,0,0)
  15827. + REGISTER(CRYPTO_DES_CBC);
  15828. + REGISTER(CRYPTO_3DES_CBC);
  15829. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  15830. + REGISTER(CRYPTO_MD5);
  15831. + REGISTER(CRYPTO_SHA1);
  15832. + REGISTER(CRYPTO_MD5_HMAC);
  15833. + REGISTER(CRYPTO_SHA1_HMAC);
  15834. +#undef REGISTER
  15835. +
  15836. + return 0;
  15837. +}
  15838. +
  15839. +static void
  15840. +null_exit(void)
  15841. +{
  15842. + dprintk("%s()\n", __FUNCTION__);
  15843. + crypto_unregister_all(null_id);
  15844. + null_id = -1;
  15845. +}
  15846. +
  15847. +module_init(null_init);
  15848. +module_exit(null_exit);
  15849. +
  15850. +MODULE_LICENSE("Dual BSD/GPL");
  15851. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  15852. +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
  15853. diff -Nur linux-2.6.29.1.orig/crypto/ocf/pasemi/Makefile linux-2.6.29.1/crypto/ocf/pasemi/Makefile
  15854. --- linux-2.6.29.1.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
  15855. +++ linux-2.6.29.1/crypto/ocf/pasemi/Makefile 2009-04-20 20:01:21.556559496 +0200
  15856. @@ -0,0 +1,12 @@
  15857. +# for SGlinux builds
  15858. +-include $(ROOTDIR)/modules/.config
  15859. +
  15860. +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
  15861. +
  15862. +obj ?= .
  15863. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  15864. +
  15865. +ifdef TOPDIR
  15866. +-include $(TOPDIR)/Rules.make
  15867. +endif
  15868. +
  15869. diff -Nur linux-2.6.29.1.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.29.1/crypto/ocf/pasemi/pasemi.c
  15870. --- linux-2.6.29.1.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
  15871. +++ linux-2.6.29.1/crypto/ocf/pasemi/pasemi.c 2009-04-20 20:01:21.556559496 +0200
  15872. @@ -0,0 +1,1009 @@
  15873. +/*
  15874. + * Copyright (C) 2007 PA Semi, Inc
  15875. + *
  15876. + * Driver for the PA Semi PWRficient DMA Crypto Engine
  15877. + *
  15878. + * This program is free software; you can redistribute it and/or modify
  15879. + * it under the terms of the GNU General Public License version 2 as
  15880. + * published by the Free Software Foundation.
  15881. + *
  15882. + * This program is distributed in the hope that it will be useful,
  15883. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15884. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15885. + * GNU General Public License for more details.
  15886. + *
  15887. + * You should have received a copy of the GNU General Public License
  15888. + * along with this program; if not, write to the Free Software
  15889. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15890. + */
  15891. +
  15892. +#ifndef AUTOCONF_INCLUDED
  15893. +#include <linux/config.h>
  15894. +#endif
  15895. +#include <linux/module.h>
  15896. +#include <linux/init.h>
  15897. +#include <linux/interrupt.h>
  15898. +#include <linux/timer.h>
  15899. +#include <linux/random.h>
  15900. +#include <linux/skbuff.h>
  15901. +#include <asm/scatterlist.h>
  15902. +#include <linux/moduleparam.h>
  15903. +#include <linux/pci.h>
  15904. +#include <cryptodev.h>
  15905. +#include <uio.h>
  15906. +#include "pasemi_fnu.h"
  15907. +
  15908. +#define DRV_NAME "pasemi"
  15909. +
  15910. +#define TIMER_INTERVAL 1000
  15911. +
  15912. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
  15913. +static struct pasdma_status volatile * dma_status;
  15914. +
  15915. +static int debug;
  15916. +module_param(debug, int, 0644);
  15917. +MODULE_PARM_DESC(debug, "Enable debug");
  15918. +
  15919. +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
  15920. +{
  15921. + desc->postop = 0;
  15922. + desc->quad[0] = hdr;
  15923. + desc->quad_cnt = 1;
  15924. + desc->size = 1;
  15925. +}
  15926. +
  15927. +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
  15928. +{
  15929. + desc->quad[desc->quad_cnt++] = val;
  15930. + desc->size = (desc->quad_cnt + 1) / 2;
  15931. +}
  15932. +
  15933. +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
  15934. +{
  15935. + desc->quad[0] |= hdr;
  15936. +}
  15937. +
  15938. +static int pasemi_desc_size(struct pasemi_desc *desc)
  15939. +{
  15940. + return desc->size;
  15941. +}
  15942. +
  15943. +static void pasemi_ring_add_desc(
  15944. + struct pasemi_fnu_txring *ring,
  15945. + struct pasemi_desc *desc,
  15946. + struct cryptop *crp) {
  15947. + int i;
  15948. + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  15949. +
  15950. + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
  15951. + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
  15952. + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
  15953. +
  15954. + for (i = 0; i < desc->quad_cnt; i += 2) {
  15955. + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  15956. + ring->desc[ring_index] = desc->quad[i];
  15957. + ring->desc[ring_index + 1] = desc->quad[i + 1];
  15958. + ring->next_to_fill++;
  15959. + }
  15960. +
  15961. + if (desc->quad_cnt & 1)
  15962. + ring->desc[ring_index + 1] = 0;
  15963. +}
  15964. +
  15965. +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
  15966. +{
  15967. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
  15968. + incr);
  15969. +}
  15970. +
  15971. +/*
  15972. + * Generate a new software session.
  15973. + */
  15974. +static int
  15975. +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  15976. +{
  15977. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  15978. + struct pasemi_softc *sc = device_get_softc(dev);
  15979. + struct pasemi_session *ses = NULL, **sespp;
  15980. + int sesn, blksz = 0;
  15981. + u64 ccmd = 0;
  15982. + unsigned long flags;
  15983. + struct pasemi_desc init_desc;
  15984. + struct pasemi_fnu_txring *txring;
  15985. +
  15986. + DPRINTF("%s()\n", __FUNCTION__);
  15987. + if (sidp == NULL || cri == NULL || sc == NULL) {
  15988. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  15989. + return -EINVAL;
  15990. + }
  15991. + for (c = cri; c != NULL; c = c->cri_next) {
  15992. + if (ALG_IS_SIG(c->cri_alg)) {
  15993. + if (macini)
  15994. + return -EINVAL;
  15995. + macini = c;
  15996. + } else if (ALG_IS_CIPHER(c->cri_alg)) {
  15997. + if (encini)
  15998. + return -EINVAL;
  15999. + encini = c;
  16000. + } else {
  16001. + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
  16002. + return -EINVAL;
  16003. + }
  16004. + }
  16005. + if (encini == NULL && macini == NULL)
  16006. + return -EINVAL;
  16007. + if (encini) {
  16008. + /* validate key length */
  16009. + switch (encini->cri_alg) {
  16010. + case CRYPTO_DES_CBC:
  16011. + if (encini->cri_klen != 64)
  16012. + return -EINVAL;
  16013. + ccmd = DMA_CALGO_DES;
  16014. + break;
  16015. + case CRYPTO_3DES_CBC:
  16016. + if (encini->cri_klen != 192)
  16017. + return -EINVAL;
  16018. + ccmd = DMA_CALGO_3DES;
  16019. + break;
  16020. + case CRYPTO_AES_CBC:
  16021. + if (encini->cri_klen != 128 &&
  16022. + encini->cri_klen != 192 &&
  16023. + encini->cri_klen != 256)
  16024. + return -EINVAL;
  16025. + ccmd = DMA_CALGO_AES;
  16026. + break;
  16027. + case CRYPTO_ARC4:
  16028. + if (encini->cri_klen != 128)
  16029. + return -EINVAL;
  16030. + ccmd = DMA_CALGO_ARC;
  16031. + break;
  16032. + default:
  16033. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  16034. + encini->cri_alg);
  16035. + return -EINVAL;
  16036. + }
  16037. + }
  16038. +
  16039. + if (macini) {
  16040. + switch (macini->cri_alg) {
  16041. + case CRYPTO_MD5:
  16042. + case CRYPTO_MD5_HMAC:
  16043. + blksz = 16;
  16044. + break;
  16045. + case CRYPTO_SHA1:
  16046. + case CRYPTO_SHA1_HMAC:
  16047. + blksz = 20;
  16048. + break;
  16049. + default:
  16050. + DPRINTF("UNKNOWN macini->cri_alg %d\n",
  16051. + macini->cri_alg);
  16052. + return -EINVAL;
  16053. + }
  16054. + if (((macini->cri_klen + 7) / 8) > blksz) {
  16055. + DPRINTF("key length %d bigger than blksize %d not supported\n",
  16056. + ((macini->cri_klen + 7) / 8), blksz);
  16057. + return -EINVAL;
  16058. + }
  16059. + }
  16060. +
  16061. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  16062. + if (sc->sc_sessions[sesn] == NULL) {
  16063. + sc->sc_sessions[sesn] = (struct pasemi_session *)
  16064. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  16065. + ses = sc->sc_sessions[sesn];
  16066. + break;
  16067. + } else if (sc->sc_sessions[sesn]->used == 0) {
  16068. + ses = sc->sc_sessions[sesn];
  16069. + break;
  16070. + }
  16071. + }
  16072. +
  16073. + if (ses == NULL) {
  16074. + sespp = (struct pasemi_session **)
  16075. + kzalloc(sc->sc_nsessions * 2 *
  16076. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  16077. + if (sespp == NULL)
  16078. + return -ENOMEM;
  16079. + memcpy(sespp, sc->sc_sessions,
  16080. + sc->sc_nsessions * sizeof(struct pasemi_session *));
  16081. + kfree(sc->sc_sessions);
  16082. + sc->sc_sessions = sespp;
  16083. + sesn = sc->sc_nsessions;
  16084. + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
  16085. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  16086. + if (ses == NULL)
  16087. + return -ENOMEM;
  16088. + sc->sc_nsessions *= 2;
  16089. + }
  16090. +
  16091. + ses->used = 1;
  16092. +
  16093. + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
  16094. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  16095. +
  16096. + /* enter the channel scheduler */
  16097. + spin_lock_irqsave(&sc->sc_chnlock, flags);
  16098. +
  16099. + /* ARC4 has to be processed by the even channel */
  16100. + if (encini && (encini->cri_alg == CRYPTO_ARC4))
  16101. + ses->chan = sc->sc_lastchn & ~1;
  16102. + else
  16103. + ses->chan = sc->sc_lastchn;
  16104. + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
  16105. +
  16106. + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
  16107. +
  16108. + txring = &sc->tx[ses->chan];
  16109. +
  16110. + if (encini) {
  16111. + ses->ccmd = ccmd;
  16112. +
  16113. + /* get an IV */
  16114. + /* XXX may read fewer than requested */
  16115. + get_random_bytes(ses->civ, sizeof(ses->civ));
  16116. +
  16117. + ses->keysz = (encini->cri_klen - 63) / 64;
  16118. + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
  16119. +
  16120. + pasemi_desc_start(&init_desc,
  16121. + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
  16122. + pasemi_desc_build(&init_desc,
  16123. + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
  16124. + }
  16125. + if (macini) {
  16126. + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
  16127. + macini->cri_alg == CRYPTO_SHA1_HMAC)
  16128. + memcpy(ses->hkey, macini->cri_key, blksz);
  16129. + else {
  16130. + /* Load initialization constants(RFC 1321, 3174) */
  16131. + ses->hiv[0] = 0x67452301efcdab89ULL;
  16132. + ses->hiv[1] = 0x98badcfe10325476ULL;
  16133. + ses->hiv[2] = 0xc3d2e1f000000000ULL;
  16134. + }
  16135. + ses->hseq = 0ULL;
  16136. + }
  16137. +
  16138. + spin_lock_irqsave(&txring->fill_lock, flags);
  16139. +
  16140. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
  16141. + txring->next_to_clean) > TX_RING_SIZE) {
  16142. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  16143. + return ERESTART;
  16144. + }
  16145. +
  16146. + if (encini) {
  16147. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  16148. + pasemi_ring_incr(sc, ses->chan,
  16149. + pasemi_desc_size(&init_desc));
  16150. + }
  16151. +
  16152. + txring->sesn = sesn;
  16153. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  16154. +
  16155. + *sidp = PASEMI_SID(sesn);
  16156. + return 0;
  16157. +}
  16158. +
  16159. +/*
  16160. + * Deallocate a session.
  16161. + */
  16162. +static int
  16163. +pasemi_freesession(device_t dev, u_int64_t tid)
  16164. +{
  16165. + struct pasemi_softc *sc = device_get_softc(dev);
  16166. + int session;
  16167. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  16168. +
  16169. + DPRINTF("%s()\n", __FUNCTION__);
  16170. +
  16171. + if (sc == NULL)
  16172. + return -EINVAL;
  16173. + session = PASEMI_SESSION(sid);
  16174. + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
  16175. + return -EINVAL;
  16176. +
  16177. + pci_unmap_single(sc->dma_pdev,
  16178. + sc->sc_sessions[session]->dma_addr,
  16179. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  16180. + memset(sc->sc_sessions[session], 0,
  16181. + sizeof(struct pasemi_session));
  16182. +
  16183. + return 0;
  16184. +}
  16185. +
  16186. +static int
  16187. +pasemi_process(device_t dev, struct cryptop *crp, int hint)
  16188. +{
  16189. +
  16190. + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
  16191. + struct pasemi_softc *sc = device_get_softc(dev);
  16192. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  16193. + caddr_t ivp;
  16194. + struct pasemi_desc init_desc, work_desc;
  16195. + struct pasemi_session *ses;
  16196. + struct sk_buff *skb;
  16197. + struct uio *uiop;
  16198. + unsigned long flags;
  16199. + struct pasemi_fnu_txring *txring;
  16200. +
  16201. + DPRINTF("%s()\n", __FUNCTION__);
  16202. +
  16203. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
  16204. + return -EINVAL;
  16205. +
  16206. + crp->crp_etype = 0;
  16207. + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
  16208. + return -EINVAL;
  16209. +
  16210. + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
  16211. +
  16212. + crd1 = crp->crp_desc;
  16213. + if (crd1 == NULL) {
  16214. + err = -EINVAL;
  16215. + goto errout;
  16216. + }
  16217. + crd2 = crd1->crd_next;
  16218. +
  16219. + if (ALG_IS_SIG(crd1->crd_alg)) {
  16220. + maccrd = crd1;
  16221. + if (crd2 == NULL)
  16222. + enccrd = NULL;
  16223. + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
  16224. + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
  16225. + enccrd = crd2;
  16226. + else
  16227. + goto erralg;
  16228. + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
  16229. + enccrd = crd1;
  16230. + if (crd2 == NULL)
  16231. + maccrd = NULL;
  16232. + else if (ALG_IS_SIG(crd2->crd_alg) &&
  16233. + (crd1->crd_flags & CRD_F_ENCRYPT))
  16234. + maccrd = crd2;
  16235. + else
  16236. + goto erralg;
  16237. + } else
  16238. + goto erralg;
  16239. +
  16240. + chsel = ses->chan;
  16241. +
  16242. + txring = &sc->tx[chsel];
  16243. +
  16244. + if (enccrd && !maccrd) {
  16245. + if (enccrd->crd_alg == CRYPTO_ARC4)
  16246. + reinit = 1;
  16247. + reinit_size = 0x40;
  16248. + srclen = crp->crp_ilen;
  16249. +
  16250. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
  16251. + | XCT_FUN_FUN(chsel));
  16252. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  16253. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
  16254. + else
  16255. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
  16256. + } else if (enccrd && maccrd) {
  16257. + if (enccrd->crd_alg == CRYPTO_ARC4)
  16258. + reinit = 1;
  16259. + reinit_size = 0x68;
  16260. +
  16261. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  16262. + /* Encrypt -> Authenticate */
  16263. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
  16264. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  16265. + srclen = maccrd->crd_skip + maccrd->crd_len;
  16266. + } else {
  16267. + /* Authenticate -> Decrypt */
  16268. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
  16269. + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
  16270. + pasemi_desc_build(&work_desc, 0);
  16271. + pasemi_desc_build(&work_desc, 0);
  16272. + pasemi_desc_build(&work_desc, 0);
  16273. + work_desc.postop = PASEMI_CHECK_SIG;
  16274. + srclen = crp->crp_ilen;
  16275. + }
  16276. +
  16277. + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
  16278. + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
  16279. + } else if (!enccrd && maccrd) {
  16280. + srclen = maccrd->crd_len;
  16281. +
  16282. + pasemi_desc_start(&init_desc,
  16283. + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
  16284. + pasemi_desc_build(&init_desc,
  16285. + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
  16286. +
  16287. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
  16288. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  16289. + }
  16290. +
  16291. + if (enccrd) {
  16292. + switch (enccrd->crd_alg) {
  16293. + case CRYPTO_3DES_CBC:
  16294. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
  16295. + XCT_FUN_BCM_CBC);
  16296. + ivsize = sizeof(u64);
  16297. + break;
  16298. + case CRYPTO_DES_CBC:
  16299. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
  16300. + XCT_FUN_BCM_CBC);
  16301. + ivsize = sizeof(u64);
  16302. + break;
  16303. + case CRYPTO_AES_CBC:
  16304. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
  16305. + XCT_FUN_BCM_CBC);
  16306. + ivsize = 2 * sizeof(u64);
  16307. + break;
  16308. + case CRYPTO_ARC4:
  16309. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
  16310. + ivsize = 0;
  16311. + break;
  16312. + default:
  16313. + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
  16314. + enccrd->crd_alg);
  16315. + err = -EINVAL;
  16316. + goto errout;
  16317. + }
  16318. +
  16319. + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
  16320. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  16321. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16322. + memcpy(ivp, enccrd->crd_iv, ivsize);
  16323. + /* If IV is not present in the buffer already, it has to be copied there */
  16324. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
  16325. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  16326. + enccrd->crd_inject, ivsize, ivp);
  16327. + } else {
  16328. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16329. + /* IV is provided expicitly in descriptor */
  16330. + memcpy(ivp, enccrd->crd_iv, ivsize);
  16331. + else
  16332. + /* IV is provided in the packet */
  16333. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  16334. + enccrd->crd_inject, ivsize,
  16335. + ivp);
  16336. + }
  16337. + }
  16338. +
  16339. + if (maccrd) {
  16340. + switch (maccrd->crd_alg) {
  16341. + case CRYPTO_MD5:
  16342. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
  16343. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16344. + break;
  16345. + case CRYPTO_SHA1:
  16346. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
  16347. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16348. + break;
  16349. + case CRYPTO_MD5_HMAC:
  16350. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
  16351. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16352. + break;
  16353. + case CRYPTO_SHA1_HMAC:
  16354. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
  16355. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  16356. + break;
  16357. + default:
  16358. + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
  16359. + maccrd->crd_alg);
  16360. + err = -EINVAL;
  16361. + goto errout;
  16362. + }
  16363. + }
  16364. +
  16365. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  16366. + /* using SKB buffers */
  16367. + skb = (struct sk_buff *)crp->crp_buf;
  16368. + if (skb_shinfo(skb)->nr_frags) {
  16369. + printk(DRV_NAME ": skb frags unimplemented\n");
  16370. + err = -EINVAL;
  16371. + goto errout;
  16372. + }
  16373. + pasemi_desc_build(
  16374. + &work_desc,
  16375. + XCT_FUN_DST_PTR(skb->len, pci_map_single(
  16376. + sc->dma_pdev, skb->data,
  16377. + skb->len, DMA_TO_DEVICE)));
  16378. + pasemi_desc_build(
  16379. + &work_desc,
  16380. + XCT_FUN_SRC_PTR(
  16381. + srclen, pci_map_single(
  16382. + sc->dma_pdev, skb->data,
  16383. + srclen, DMA_TO_DEVICE)));
  16384. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  16385. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  16386. + /* using IOV buffers */
  16387. + uiop = (struct uio *)crp->crp_buf;
  16388. + if (uiop->uio_iovcnt > 1) {
  16389. + printk(DRV_NAME ": iov frags unimplemented\n");
  16390. + err = -EINVAL;
  16391. + goto errout;
  16392. + }
  16393. +
  16394. + /* crp_olen is never set; always use crp_ilen */
  16395. + pasemi_desc_build(
  16396. + &work_desc,
  16397. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  16398. + sc->dma_pdev,
  16399. + uiop->uio_iov->iov_base,
  16400. + crp->crp_ilen, DMA_TO_DEVICE)));
  16401. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  16402. +
  16403. + pasemi_desc_build(
  16404. + &work_desc,
  16405. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  16406. + sc->dma_pdev,
  16407. + uiop->uio_iov->iov_base,
  16408. + srclen, DMA_TO_DEVICE)));
  16409. + } else {
  16410. + /* using contig buffers */
  16411. + pasemi_desc_build(
  16412. + &work_desc,
  16413. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  16414. + sc->dma_pdev,
  16415. + crp->crp_buf,
  16416. + crp->crp_ilen, DMA_TO_DEVICE)));
  16417. + pasemi_desc_build(
  16418. + &work_desc,
  16419. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  16420. + sc->dma_pdev,
  16421. + crp->crp_buf, srclen,
  16422. + DMA_TO_DEVICE)));
  16423. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  16424. + }
  16425. +
  16426. + spin_lock_irqsave(&txring->fill_lock, flags);
  16427. +
  16428. + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
  16429. + txring->sesn = PASEMI_SESSION(crp->crp_sid);
  16430. + reinit = 1;
  16431. + }
  16432. +
  16433. + if (enccrd) {
  16434. + pasemi_desc_start(&init_desc,
  16435. + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
  16436. + pasemi_desc_build(&init_desc,
  16437. + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
  16438. + }
  16439. +
  16440. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
  16441. + pasemi_desc_size(&work_desc)) -
  16442. + txring->next_to_clean) > TX_RING_SIZE) {
  16443. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  16444. + err = ERESTART;
  16445. + goto errout;
  16446. + }
  16447. +
  16448. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  16449. + pasemi_ring_add_desc(txring, &work_desc, crp);
  16450. +
  16451. + pasemi_ring_incr(sc, chsel,
  16452. + pasemi_desc_size(&init_desc) +
  16453. + pasemi_desc_size(&work_desc));
  16454. +
  16455. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  16456. +
  16457. + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
  16458. +
  16459. + return 0;
  16460. +
  16461. +erralg:
  16462. + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
  16463. + crd1->crd_alg, crd2->crd_alg);
  16464. + err = -EINVAL;
  16465. +
  16466. +errout:
  16467. + if (err != ERESTART) {
  16468. + crp->crp_etype = err;
  16469. + crypto_done(crp);
  16470. + }
  16471. + return err;
  16472. +}
  16473. +
  16474. +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
  16475. +{
  16476. + int i, j, ring_idx;
  16477. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  16478. + u16 delta_cnt;
  16479. + int flags, loops = 10;
  16480. + int desc_size;
  16481. + struct cryptop *crp;
  16482. +
  16483. + spin_lock_irqsave(&ring->clean_lock, flags);
  16484. +
  16485. + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
  16486. + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
  16487. + && loops--) {
  16488. +
  16489. + for (i = 0; i < delta_cnt; i++) {
  16490. + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
  16491. + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
  16492. + if (crp) {
  16493. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  16494. + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
  16495. + /* Need to make sure signature matched,
  16496. + * if not - return error */
  16497. + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
  16498. + crp->crp_etype = -EINVAL;
  16499. + }
  16500. + crypto_done(TX_DESC_INFO(ring,
  16501. + ring->next_to_clean).cf_crp);
  16502. + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
  16503. + pci_unmap_single(
  16504. + sc->dma_pdev,
  16505. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
  16506. + PCI_DMA_TODEVICE);
  16507. +
  16508. + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
  16509. +
  16510. + ring->next_to_clean++;
  16511. + for (j = 1; j < desc_size; j++) {
  16512. + ring_idx = 2 *
  16513. + (ring->next_to_clean &
  16514. + (TX_RING_SIZE-1));
  16515. + pci_unmap_single(
  16516. + sc->dma_pdev,
  16517. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
  16518. + PCI_DMA_TODEVICE);
  16519. + if (ring->desc[ring_idx + 1])
  16520. + pci_unmap_single(
  16521. + sc->dma_pdev,
  16522. + XCT_PTR_ADDR_LEN(
  16523. + ring->desc[
  16524. + ring_idx + 1]),
  16525. + PCI_DMA_TODEVICE);
  16526. + ring->desc[ring_idx] =
  16527. + ring->desc[ring_idx + 1] = 0;
  16528. + ring->next_to_clean++;
  16529. + }
  16530. + } else {
  16531. + for (j = 0; j < desc_size; j++) {
  16532. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  16533. + ring->desc[ring_idx] =
  16534. + ring->desc[ring_idx + 1] = 0;
  16535. + ring->next_to_clean++;
  16536. + }
  16537. + }
  16538. + }
  16539. +
  16540. + ring->total_pktcnt += delta_cnt;
  16541. + }
  16542. + spin_unlock_irqrestore(&ring->clean_lock, flags);
  16543. +
  16544. + return 0;
  16545. +}
  16546. +
  16547. +static void sweepup_tx(struct pasemi_softc *sc)
  16548. +{
  16549. + int i;
  16550. +
  16551. + for (i = 0; i < sc->sc_num_channels; i++)
  16552. + pasemi_clean_tx(sc, i);
  16553. +}
  16554. +
  16555. +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
  16556. +{
  16557. + struct pasemi_softc *sc = arg;
  16558. + unsigned int reg;
  16559. + int chan = irq - sc->base_irq;
  16560. + int chan_index = sc->base_chan + chan;
  16561. + u64 stat = dma_status->tx_sta[chan_index];
  16562. +
  16563. + DPRINTF("%s()\n", __FUNCTION__);
  16564. +
  16565. + if (!(stat & PAS_STATUS_CAUSE_M))
  16566. + return IRQ_NONE;
  16567. +
  16568. + pasemi_clean_tx(sc, chan);
  16569. +
  16570. + stat = dma_status->tx_sta[chan_index];
  16571. +
  16572. + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
  16573. + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
  16574. +
  16575. + if (stat & PAS_STATUS_SOFT)
  16576. + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
  16577. +
  16578. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
  16579. +
  16580. +
  16581. + return IRQ_HANDLED;
  16582. +}
  16583. +
  16584. +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
  16585. +{
  16586. + u32 val;
  16587. + int chan_index = chan + sc->base_chan;
  16588. + int ret;
  16589. + struct pasemi_fnu_txring *ring;
  16590. +
  16591. + ring = &sc->tx[chan];
  16592. +
  16593. + spin_lock_init(&ring->fill_lock);
  16594. + spin_lock_init(&ring->clean_lock);
  16595. +
  16596. + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
  16597. + TX_RING_SIZE, GFP_KERNEL);
  16598. + if (!ring->desc_info)
  16599. + return -ENOMEM;
  16600. +
  16601. + /* Allocate descriptors */
  16602. + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
  16603. + TX_RING_SIZE *
  16604. + 2 * sizeof(u64),
  16605. + &ring->dma, GFP_KERNEL);
  16606. + if (!ring->desc)
  16607. + return -ENOMEM;
  16608. +
  16609. + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
  16610. +
  16611. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
  16612. +
  16613. + ring->total_pktcnt = 0;
  16614. +
  16615. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
  16616. + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
  16617. +
  16618. + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
  16619. + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
  16620. +
  16621. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
  16622. +
  16623. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
  16624. + PAS_DMA_TXCHAN_CFG_TY_FUNC |
  16625. + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
  16626. + PAS_DMA_TXCHAN_CFG_WT(2));
  16627. +
  16628. + /* enable tx channel */
  16629. + out_le32(sc->dma_regs +
  16630. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  16631. + PAS_DMA_TXCHAN_TCMDSTA_EN);
  16632. +
  16633. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
  16634. + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
  16635. +
  16636. + ring->next_to_fill = 0;
  16637. + ring->next_to_clean = 0;
  16638. +
  16639. + snprintf(ring->irq_name, sizeof(ring->irq_name),
  16640. + "%s%d", "crypto", chan);
  16641. +
  16642. + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
  16643. + ret = request_irq(ring->irq, (irq_handler_t)
  16644. + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
  16645. + if (ret) {
  16646. + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
  16647. + ring->irq, ret);
  16648. + ring->irq = -1;
  16649. + return ret;
  16650. + }
  16651. +
  16652. + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
  16653. +
  16654. + return 0;
  16655. +}
  16656. +
  16657. +static device_method_t pasemi_methods = {
  16658. + /* crypto device methods */
  16659. + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
  16660. + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
  16661. + DEVMETHOD(cryptodev_process, pasemi_process),
  16662. +};
  16663. +
  16664. +/* Set up the crypto device structure, private data,
  16665. + * and anything else we need before we start */
  16666. +
  16667. +static int __devinit
  16668. +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  16669. +{
  16670. + struct pasemi_softc *sc;
  16671. + int ret, i;
  16672. +
  16673. + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
  16674. +
  16675. + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
  16676. + if (!sc)
  16677. + return -ENOMEM;
  16678. +
  16679. + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
  16680. +
  16681. + pci_set_drvdata(pdev, sc);
  16682. +
  16683. + spin_lock_init(&sc->sc_chnlock);
  16684. +
  16685. + sc->sc_sessions = (struct pasemi_session **)
  16686. + kzalloc(PASEMI_INITIAL_SESSIONS *
  16687. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  16688. + if (sc->sc_sessions == NULL) {
  16689. + ret = -ENOMEM;
  16690. + goto out;
  16691. + }
  16692. +
  16693. + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
  16694. + sc->sc_lastchn = 0;
  16695. + sc->base_irq = pdev->irq + 6;
  16696. + sc->base_chan = 6;
  16697. + sc->sc_cid = -1;
  16698. + sc->dma_pdev = pdev;
  16699. +
  16700. + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
  16701. + if (!sc->iob_pdev) {
  16702. + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
  16703. + ret = -ENODEV;
  16704. + goto out;
  16705. + }
  16706. +
  16707. + /* This is hardcoded and ugly, but we have some firmware versions
  16708. + * who don't provide the register space in the device tree. Luckily
  16709. + * they are at well-known locations so we can just do the math here.
  16710. + */
  16711. + sc->dma_regs =
  16712. + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
  16713. + sc->iob_regs =
  16714. + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
  16715. + if (!sc->dma_regs || !sc->iob_regs) {
  16716. + dev_err(&pdev->dev, "Can't map registers\n");
  16717. + ret = -ENODEV;
  16718. + goto out;
  16719. + }
  16720. +
  16721. + dma_status = __ioremap(0xfd800000, 0x1000, 0);
  16722. + if (!dma_status) {
  16723. + ret = -ENODEV;
  16724. + dev_err(&pdev->dev, "Can't map dmastatus space\n");
  16725. + goto out;
  16726. + }
  16727. +
  16728. + sc->tx = (struct pasemi_fnu_txring *)
  16729. + kzalloc(sizeof(struct pasemi_fnu_txring)
  16730. + * 8, GFP_KERNEL);
  16731. + if (!sc->tx) {
  16732. + ret = -ENOMEM;
  16733. + goto out;
  16734. + }
  16735. +
  16736. + /* Initialize the h/w */
  16737. + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
  16738. + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
  16739. + PAS_DMA_COM_CFG_FWF));
  16740. + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
  16741. +
  16742. + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
  16743. + sc->sc_num_channels++;
  16744. + ret = pasemi_dma_setup_tx_resources(sc, i);
  16745. + if (ret)
  16746. + goto out;
  16747. + }
  16748. +
  16749. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
  16750. + CRYPTOCAP_F_HARDWARE);
  16751. + if (sc->sc_cid < 0) {
  16752. + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
  16753. + ret = -ENXIO;
  16754. + goto out;
  16755. + }
  16756. +
  16757. + /* register algorithms with the framework */
  16758. + printk(DRV_NAME ":");
  16759. +
  16760. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  16761. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  16762. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  16763. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  16764. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  16765. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  16766. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  16767. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  16768. +
  16769. + return 0;
  16770. +
  16771. +out:
  16772. + pasemi_dma_remove(pdev);
  16773. + return ret;
  16774. +}
  16775. +
  16776. +#define MAX_RETRIES 5000
  16777. +
  16778. +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
  16779. +{
  16780. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  16781. + int chan_index = chan + sc->base_chan;
  16782. + int retries;
  16783. + u32 stat;
  16784. +
  16785. + /* Stop the channel */
  16786. + out_le32(sc->dma_regs +
  16787. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  16788. + PAS_DMA_TXCHAN_TCMDSTA_ST);
  16789. +
  16790. + for (retries = 0; retries < MAX_RETRIES; retries++) {
  16791. + stat = in_le32(sc->dma_regs +
  16792. + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
  16793. + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
  16794. + break;
  16795. + cond_resched();
  16796. + }
  16797. +
  16798. + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
  16799. + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
  16800. + chan_index);
  16801. +
  16802. + /* Disable the channel */
  16803. + out_le32(sc->dma_regs +
  16804. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  16805. + 0);
  16806. +
  16807. + if (ring->desc_info)
  16808. + kfree((void *) ring->desc_info);
  16809. + if (ring->desc)
  16810. + dma_free_coherent(&sc->dma_pdev->dev,
  16811. + TX_RING_SIZE *
  16812. + 2 * sizeof(u64),
  16813. + (void *) ring->desc, ring->dma);
  16814. + if (ring->irq != -1)
  16815. + free_irq(ring->irq, sc);
  16816. +
  16817. + del_timer(&ring->crypto_timer);
  16818. +}
  16819. +
  16820. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
  16821. +{
  16822. + struct pasemi_softc *sc = pci_get_drvdata(pdev);
  16823. + int i;
  16824. +
  16825. + DPRINTF("%s()\n", __FUNCTION__);
  16826. +
  16827. + if (sc->sc_cid >= 0) {
  16828. + crypto_unregister_all(sc->sc_cid);
  16829. + }
  16830. +
  16831. + if (sc->tx) {
  16832. + for (i = 0; i < sc->sc_num_channels; i++)
  16833. + pasemi_free_tx_resources(sc, i);
  16834. +
  16835. + kfree(sc->tx);
  16836. + }
  16837. + if (sc->sc_sessions) {
  16838. + for (i = 0; i < sc->sc_nsessions; i++)
  16839. + kfree(sc->sc_sessions[i]);
  16840. + kfree(sc->sc_sessions);
  16841. + }
  16842. + if (sc->iob_pdev)
  16843. + pci_dev_put(sc->iob_pdev);
  16844. + if (sc->dma_regs)
  16845. + iounmap(sc->dma_regs);
  16846. + if (sc->iob_regs)
  16847. + iounmap(sc->iob_regs);
  16848. + kfree(sc);
  16849. +}
  16850. +
  16851. +static struct pci_device_id pasemi_dma_pci_tbl[] = {
  16852. + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
  16853. +};
  16854. +
  16855. +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
  16856. +
  16857. +static struct pci_driver pasemi_dma_driver = {
  16858. + .name = "pasemi_dma",
  16859. + .id_table = pasemi_dma_pci_tbl,
  16860. + .probe = pasemi_dma_probe,
  16861. + .remove = __devexit_p(pasemi_dma_remove),
  16862. +};
  16863. +
  16864. +static void __exit pasemi_dma_cleanup_module(void)
  16865. +{
  16866. + pci_unregister_driver(&pasemi_dma_driver);
  16867. + __iounmap(dma_status);
  16868. + dma_status = NULL;
  16869. +}
  16870. +
  16871. +int pasemi_dma_init_module(void)
  16872. +{
  16873. + return pci_register_driver(&pasemi_dma_driver);
  16874. +}
  16875. +
  16876. +module_init(pasemi_dma_init_module);
  16877. +module_exit(pasemi_dma_cleanup_module);
  16878. +
  16879. +MODULE_LICENSE("Dual BSD/GPL");
  16880. +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
  16881. +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
  16882. diff -Nur linux-2.6.29.1.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.29.1/crypto/ocf/pasemi/pasemi_fnu.h
  16883. --- linux-2.6.29.1.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
  16884. +++ linux-2.6.29.1/crypto/ocf/pasemi/pasemi_fnu.h 2009-04-20 20:01:21.560560284 +0200
  16885. @@ -0,0 +1,410 @@
  16886. +/*
  16887. + * Copyright (C) 2007 PA Semi, Inc
  16888. + *
  16889. + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
  16890. + * hardware register layouts.
  16891. + *
  16892. + * This program is free software; you can redistribute it and/or modify
  16893. + * it under the terms of the GNU General Public License version 2 as
  16894. + * published by the Free Software Foundation.
  16895. + *
  16896. + * This program is distributed in the hope that it will be useful,
  16897. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16898. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16899. + * GNU General Public License for more details.
  16900. + *
  16901. + * You should have received a copy of the GNU General Public License
  16902. + * along with this program; if not, write to the Free Software
  16903. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16904. + */
  16905. +
  16906. +#ifndef PASEMI_FNU_H
  16907. +#define PASEMI_FNU_H
  16908. +
  16909. +#include <linux/spinlock.h>
  16910. +
  16911. +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
  16912. +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
  16913. +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
  16914. +
  16915. +/* Must be a power of two */
  16916. +#define RX_RING_SIZE 512
  16917. +#define TX_RING_SIZE 512
  16918. +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
  16919. +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
  16920. +#define MAX_DESC_SIZE 8
  16921. +#define PASEMI_INITIAL_SESSIONS 10
  16922. +#define PASEMI_FNU_CHANNELS 8
  16923. +
  16924. +/* DMA descriptor */
  16925. +struct pasemi_desc {
  16926. + u64 quad[2*MAX_DESC_SIZE];
  16927. + int quad_cnt;
  16928. + int size;
  16929. + int postop;
  16930. +};
  16931. +
  16932. +/*
  16933. + * Holds per descriptor data
  16934. + */
  16935. +struct pasemi_desc_info {
  16936. + int desc_size;
  16937. + int desc_postop;
  16938. +#define PASEMI_CHECK_SIG 0x1
  16939. +
  16940. + struct cryptop *cf_crp;
  16941. +};
  16942. +
  16943. +/*
  16944. + * Holds per channel data
  16945. + */
  16946. +struct pasemi_fnu_txring {
  16947. + volatile u64 *desc;
  16948. + volatile struct
  16949. + pasemi_desc_info *desc_info;
  16950. + dma_addr_t dma;
  16951. + struct timer_list crypto_timer;
  16952. + spinlock_t fill_lock;
  16953. + spinlock_t clean_lock;
  16954. + unsigned int next_to_fill;
  16955. + unsigned int next_to_clean;
  16956. + u16 total_pktcnt;
  16957. + int irq;
  16958. + int sesn;
  16959. + char irq_name[10];
  16960. +};
  16961. +
  16962. +/*
  16963. + * Holds data specific to a single pasemi device.
  16964. + */
  16965. +struct pasemi_softc {
  16966. + softc_device_decl sc_cdev;
  16967. + struct pci_dev *dma_pdev; /* device backpointer */
  16968. + struct pci_dev *iob_pdev; /* device backpointer */
  16969. + void __iomem *dma_regs;
  16970. + void __iomem *iob_regs;
  16971. + int base_irq;
  16972. + int base_chan;
  16973. + int32_t sc_cid; /* crypto tag */
  16974. + int sc_nsessions;
  16975. + struct pasemi_session **sc_sessions;
  16976. + int sc_num_channels;/* number of crypto channels */
  16977. +
  16978. + /* pointer to the array of txring datastructures, one txring per channel */
  16979. + struct pasemi_fnu_txring *tx;
  16980. +
  16981. + /*
  16982. + * mutual exclusion for the channel scheduler
  16983. + */
  16984. + spinlock_t sc_chnlock;
  16985. + /* last channel used, for now use round-robin to allocate channels */
  16986. + int sc_lastchn;
  16987. +};
  16988. +
  16989. +struct pasemi_session {
  16990. + u64 civ[2];
  16991. + u64 keysz;
  16992. + u64 key[4];
  16993. + u64 ccmd;
  16994. + u64 hkey[4];
  16995. + u64 hseq;
  16996. + u64 giv[2];
  16997. + u64 hiv[4];
  16998. +
  16999. + int used;
  17000. + dma_addr_t dma_addr;
  17001. + int chan;
  17002. +};
  17003. +
  17004. +/* status register layout in IOB region, at 0xfd800000 */
  17005. +struct pasdma_status {
  17006. + u64 rx_sta[64];
  17007. + u64 tx_sta[20];
  17008. +};
  17009. +
  17010. +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
  17011. + (alg == CRYPTO_3DES_CBC) || \
  17012. + (alg == CRYPTO_AES_CBC) || \
  17013. + (alg == CRYPTO_ARC4) || \
  17014. + (alg == CRYPTO_NULL_CBC))
  17015. +
  17016. +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
  17017. + (alg == CRYPTO_MD5_HMAC) || \
  17018. + (alg == CRYPTO_SHA1) || \
  17019. + (alg == CRYPTO_SHA1_HMAC) || \
  17020. + (alg == CRYPTO_NULL_HMAC))
  17021. +
  17022. +enum {
  17023. + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
  17024. + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
  17025. + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
  17026. + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
  17027. + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
  17028. +};
  17029. +
  17030. +/* All these registers live in the PCI configuration space for the DMA PCI
  17031. + * device. Use the normal PCI config access functions for them.
  17032. + */
  17033. +
  17034. +#define PAS_DMA_COM_CFG_FWF 0x18000000
  17035. +
  17036. +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
  17037. +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
  17038. +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
  17039. +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
  17040. +
  17041. +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
  17042. +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
  17043. +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
  17044. +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
  17045. +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
  17046. +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
  17047. +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
  17048. +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
  17049. +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
  17050. +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
  17051. +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
  17052. +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
  17053. +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
  17054. +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
  17055. +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
  17056. +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
  17057. +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
  17058. +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
  17059. + PAS_DMA_TXCHAN_CFG_TATTR_M)
  17060. +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
  17061. +#define PAS_DMA_TXCHAN_CFG_WT_S 6
  17062. +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
  17063. + PAS_DMA_TXCHAN_CFG_WT_M)
  17064. +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
  17065. +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
  17066. +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
  17067. +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
  17068. +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
  17069. +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
  17070. +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
  17071. +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
  17072. +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
  17073. +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
  17074. + PAS_DMA_TXCHAN_BASEL_BRBL_M)
  17075. +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
  17076. +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
  17077. +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
  17078. +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
  17079. + PAS_DMA_TXCHAN_BASEU_BRBH_M)
  17080. +/* # of cache lines worth of buffer ring */
  17081. +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
  17082. +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
  17083. +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
  17084. + PAS_DMA_TXCHAN_BASEU_SIZ_M)
  17085. +
  17086. +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
  17087. +#define PAS_STATUS_PCNT_S 0
  17088. +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
  17089. +#define PAS_STATUS_DCNT_S 16
  17090. +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
  17091. +#define PAS_STATUS_BPCNT_S 32
  17092. +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
  17093. +#define PAS_STATUS_TIMER 0x1000000000000000ull
  17094. +#define PAS_STATUS_ERROR 0x2000000000000000ull
  17095. +#define PAS_STATUS_SOFT 0x4000000000000000ull
  17096. +#define PAS_STATUS_INT 0x8000000000000000ull
  17097. +
  17098. +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
  17099. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
  17100. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
  17101. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
  17102. + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
  17103. +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
  17104. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
  17105. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
  17106. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
  17107. + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
  17108. +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
  17109. +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
  17110. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
  17111. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
  17112. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
  17113. + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
  17114. +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
  17115. +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
  17116. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
  17117. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
  17118. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
  17119. + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
  17120. +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
  17121. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
  17122. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
  17123. +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
  17124. + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
  17125. +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
  17126. +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
  17127. +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
  17128. +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
  17129. +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
  17130. +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
  17131. +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
  17132. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
  17133. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
  17134. +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
  17135. + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
  17136. +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
  17137. +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
  17138. +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
  17139. +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
  17140. +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
  17141. +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
  17142. +
  17143. +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
  17144. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
  17145. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
  17146. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
  17147. + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
  17148. +
  17149. +/* Transmit descriptor fields */
  17150. +#define XCT_MACTX_T 0x8000000000000000ull
  17151. +#define XCT_MACTX_ST 0x4000000000000000ull
  17152. +#define XCT_MACTX_NORES 0x0000000000000000ull
  17153. +#define XCT_MACTX_8BRES 0x1000000000000000ull
  17154. +#define XCT_MACTX_24BRES 0x2000000000000000ull
  17155. +#define XCT_MACTX_40BRES 0x3000000000000000ull
  17156. +#define XCT_MACTX_I 0x0800000000000000ull
  17157. +#define XCT_MACTX_O 0x0400000000000000ull
  17158. +#define XCT_MACTX_E 0x0200000000000000ull
  17159. +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
  17160. +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
  17161. +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
  17162. +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
  17163. +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
  17164. +#define XCT_MACTX_CRC_M 0x0060000000000000ull
  17165. +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
  17166. +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
  17167. +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
  17168. +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
  17169. +#define XCT_MACTX_SS 0x0010000000000000ull
  17170. +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
  17171. +#define XCT_MACTX_LLEN_S 32ull
  17172. +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
  17173. + XCT_MACTX_LLEN_M)
  17174. +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
  17175. +#define XCT_MACTX_IPH_S 27ull
  17176. +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
  17177. + XCT_MACTX_IPH_M)
  17178. +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
  17179. +#define XCT_MACTX_IPO_S 22ull
  17180. +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
  17181. + XCT_MACTX_IPO_M)
  17182. +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
  17183. +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
  17184. +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
  17185. +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
  17186. +#define XCT_MACTX_V6 0x0000000000000010ull
  17187. +#define XCT_MACTX_C 0x0000000000000004ull
  17188. +#define XCT_MACTX_AL2 0x0000000000000002ull
  17189. +
  17190. +#define XCT_PTR_T 0x8000000000000000ull
  17191. +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
  17192. +#define XCT_PTR_LEN_S 44
  17193. +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
  17194. + XCT_PTR_LEN_M)
  17195. +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
  17196. +#define XCT_PTR_ADDR_S 0
  17197. +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
  17198. + XCT_PTR_ADDR_M)
  17199. +
  17200. +/* Function descriptor fields */
  17201. +#define XCT_FUN_T 0x8000000000000000ull
  17202. +#define XCT_FUN_ST 0x4000000000000000ull
  17203. +#define XCT_FUN_NORES 0x0000000000000000ull
  17204. +#define XCT_FUN_8BRES 0x1000000000000000ull
  17205. +#define XCT_FUN_24BRES 0x2000000000000000ull
  17206. +#define XCT_FUN_40BRES 0x3000000000000000ull
  17207. +#define XCT_FUN_I 0x0800000000000000ull
  17208. +#define XCT_FUN_O 0x0400000000000000ull
  17209. +#define XCT_FUN_E 0x0200000000000000ull
  17210. +#define XCT_FUN_FUN_S 54
  17211. +#define XCT_FUN_FUN_M 0x01c0000000000000ull
  17212. +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
  17213. + XCT_FUN_FUN_M)
  17214. +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
  17215. +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
  17216. +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
  17217. +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
  17218. +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
  17219. +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
  17220. +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
  17221. +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
  17222. +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
  17223. +#define XCT_FUN_LLEN_S 32ULL
  17224. +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
  17225. + XCT_FUN_LLEN_M)
  17226. +#define XCT_FUN_SHL_M 0x00000000f8000000ull
  17227. +#define XCT_FUN_SHL_S 27ull
  17228. +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
  17229. + XCT_FUN_SHL_M)
  17230. +#define XCT_FUN_CHL_M 0x0000000007c00000ull
  17231. +#define XCT_FUN_CHL_S 22ull
  17232. +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
  17233. + XCT_FUN_CHL_M)
  17234. +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
  17235. +#define XCT_FUN_HSZ_S 18ull
  17236. +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
  17237. + XCT_FUN_HSZ_M)
  17238. +#define XCT_FUN_ALG_DES 0x0000000000000000ull
  17239. +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
  17240. +#define XCT_FUN_ALG_AES 0x0000000000010000ull
  17241. +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
  17242. +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
  17243. +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
  17244. +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
  17245. +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
  17246. +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
  17247. +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
  17248. +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
  17249. +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
  17250. +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
  17251. +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
  17252. +#define XCT_FUN_BCP_PL 0x0000000000000400ull
  17253. +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
  17254. +#define XCT_FUN_SIG_MD5 (0ull << 4)
  17255. +#define XCT_FUN_SIG_SHA1 (2ull << 4)
  17256. +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
  17257. +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
  17258. +#define XCT_FUN_A 0x0000000000000008ull
  17259. +#define XCT_FUN_C 0x0000000000000004ull
  17260. +#define XCT_FUN_AL2 0x0000000000000002ull
  17261. +#define XCT_FUN_SE 0x0000000000000001ull
  17262. +
  17263. +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
  17264. +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
  17265. + 0x8000000000000000ull)
  17266. +
  17267. +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
  17268. +#define XCT_CTRL_HDR_FUN_NUM_S 54
  17269. +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
  17270. +#define XCT_CTRL_HDR_LEN_S 32
  17271. +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
  17272. +#define XCT_CTRL_HDR_REG_S 0
  17273. +
  17274. +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
  17275. + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
  17276. + & XCT_CTRL_HDR_FUN_NUM_M) | \
  17277. + ((((long)(len)) << \
  17278. + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
  17279. + ((((long)(reg)) << \
  17280. + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
  17281. +
  17282. +/* Function config command options */
  17283. +#define DMA_CALGO_DES 0x00
  17284. +#define DMA_CALGO_3DES 0x01
  17285. +#define DMA_CALGO_AES 0x02
  17286. +#define DMA_CALGO_ARC 0x03
  17287. +
  17288. +#define DMA_FN_CIV0 0x02
  17289. +#define DMA_FN_CIV1 0x03
  17290. +#define DMA_FN_HKEY0 0x0a
  17291. +
  17292. +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
  17293. + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
  17294. +
  17295. +#endif /* PASEMI_FNU_H */
  17296. diff -Nur linux-2.6.29.1.orig/crypto/ocf/random.c linux-2.6.29.1/crypto/ocf/random.c
  17297. --- linux-2.6.29.1.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
  17298. +++ linux-2.6.29.1/crypto/ocf/random.c 2009-04-20 20:01:21.584560546 +0200
  17299. @@ -0,0 +1,317 @@
  17300. +/*
  17301. + * A system independant way of adding entropy to the kernels pool
  17302. + * this way the drivers can focus on the real work and we can take
  17303. + * care of pushing it to the appropriate place in the kernel.
  17304. + *
  17305. + * This should be fast and callable from timers/interrupts
  17306. + *
  17307. + * Written by David McCullough <david_mccullough@securecomputing.com>
  17308. + * Copyright (C) 2006-2007 David McCullough
  17309. + * Copyright (C) 2004-2005 Intel Corporation.
  17310. + *
  17311. + * LICENSE TERMS
  17312. + *
  17313. + * The free distribution and use of this software in both source and binary
  17314. + * form is allowed (with or without changes) provided that:
  17315. + *
  17316. + * 1. distributions of this source code include the above copyright
  17317. + * notice, this list of conditions and the following disclaimer;
  17318. + *
  17319. + * 2. distributions in binary form include the above copyright
  17320. + * notice, this list of conditions and the following disclaimer
  17321. + * in the documentation and/or other associated materials;
  17322. + *
  17323. + * 3. the copyright holder's name is not used to endorse products
  17324. + * built using this software without specific written permission.
  17325. + *
  17326. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  17327. + * may be distributed under the terms of the GNU General Public License (GPL),
  17328. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  17329. + *
  17330. + * DISCLAIMER
  17331. + *
  17332. + * This software is provided 'as is' with no explicit or implied warranties
  17333. + * in respect of its properties, including, but not limited to, correctness
  17334. + * and/or fitness for purpose.
  17335. + */
  17336. +
  17337. +#ifndef AUTOCONF_INCLUDED
  17338. +#include <linux/config.h>
  17339. +#endif
  17340. +#include <linux/module.h>
  17341. +#include <linux/init.h>
  17342. +#include <linux/list.h>
  17343. +#include <linux/slab.h>
  17344. +#include <linux/wait.h>
  17345. +#include <linux/sched.h>
  17346. +#include <linux/spinlock.h>
  17347. +#include <linux/version.h>
  17348. +#include <linux/unistd.h>
  17349. +#include <linux/poll.h>
  17350. +#include <linux/random.h>
  17351. +#include <cryptodev.h>
  17352. +
  17353. +#ifdef CONFIG_OCF_FIPS
  17354. +#include "rndtest.h"
  17355. +#endif
  17356. +
  17357. +#ifndef HAS_RANDOM_INPUT_WAIT
  17358. +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
  17359. +#endif
  17360. +
  17361. +/*
  17362. + * a hack to access the debug levels from the crypto driver
  17363. + */
  17364. +extern int crypto_debug;
  17365. +#define debug crypto_debug
  17366. +
  17367. +/*
  17368. + * a list of all registered random providers
  17369. + */
  17370. +static LIST_HEAD(random_ops);
  17371. +static int started = 0;
  17372. +static int initted = 0;
  17373. +
  17374. +struct random_op {
  17375. + struct list_head random_list;
  17376. + u_int32_t driverid;
  17377. + int (*read_random)(void *arg, u_int32_t *buf, int len);
  17378. + void *arg;
  17379. +};
  17380. +
  17381. +static int random_proc(void *arg);
  17382. +
  17383. +static pid_t randomproc = (pid_t) -1;
  17384. +static spinlock_t random_lock;
  17385. +
  17386. +/*
  17387. + * just init the spin locks
  17388. + */
  17389. +static int
  17390. +crypto_random_init(void)
  17391. +{
  17392. + spin_lock_init(&random_lock);
  17393. + initted = 1;
  17394. + return(0);
  17395. +}
  17396. +
  17397. +/*
  17398. + * Add the given random reader to our list (if not present)
  17399. + * and start the thread (if not already started)
  17400. + *
  17401. + * we have to assume that driver id is ok for now
  17402. + */
  17403. +int
  17404. +crypto_rregister(
  17405. + u_int32_t driverid,
  17406. + int (*read_random)(void *arg, u_int32_t *buf, int len),
  17407. + void *arg)
  17408. +{
  17409. + unsigned long flags;
  17410. + int ret = 0;
  17411. + struct random_op *rops, *tmp;
  17412. +
  17413. + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
  17414. + __FUNCTION__, driverid, read_random, arg);
  17415. +
  17416. + if (!initted)
  17417. + crypto_random_init();
  17418. +
  17419. +#if 0
  17420. + struct cryptocap *cap;
  17421. +
  17422. + cap = crypto_checkdriver(driverid);
  17423. + if (!cap)
  17424. + return EINVAL;
  17425. +#endif
  17426. +
  17427. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  17428. + if (rops->driverid == driverid && rops->read_random == read_random)
  17429. + return EEXIST;
  17430. + }
  17431. +
  17432. + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
  17433. + if (!rops)
  17434. + return ENOMEM;
  17435. +
  17436. + rops->driverid = driverid;
  17437. + rops->read_random = read_random;
  17438. + rops->arg = arg;
  17439. +
  17440. + spin_lock_irqsave(&random_lock, flags);
  17441. + list_add_tail(&rops->random_list, &random_ops);
  17442. + if (!started) {
  17443. + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
  17444. + if (randomproc < 0) {
  17445. + ret = randomproc;
  17446. + printk("crypto: crypto_rregister cannot start random thread; "
  17447. + "error %d", ret);
  17448. + } else
  17449. + started = 1;
  17450. + }
  17451. + spin_unlock_irqrestore(&random_lock, flags);
  17452. +
  17453. + return ret;
  17454. +}
  17455. +EXPORT_SYMBOL(crypto_rregister);
  17456. +
  17457. +int
  17458. +crypto_runregister_all(u_int32_t driverid)
  17459. +{
  17460. + struct random_op *rops, *tmp;
  17461. + unsigned long flags;
  17462. +
  17463. + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
  17464. +
  17465. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  17466. + if (rops->driverid == driverid) {
  17467. + list_del(&rops->random_list);
  17468. + kfree(rops);
  17469. + }
  17470. + }
  17471. +
  17472. + spin_lock_irqsave(&random_lock, flags);
  17473. + if (list_empty(&random_ops) && started)
  17474. + kill_pid(randomproc, SIGKILL, 1);
  17475. + spin_unlock_irqrestore(&random_lock, flags);
  17476. + return(0);
  17477. +}
  17478. +EXPORT_SYMBOL(crypto_runregister_all);
  17479. +
  17480. +/*
  17481. + * while we can add entropy to random.c continue to read random data from
  17482. + * the drivers and push it to random.
  17483. + */
  17484. +static int
  17485. +random_proc(void *arg)
  17486. +{
  17487. + int n;
  17488. + int wantcnt;
  17489. + int bufcnt = 0;
  17490. + int retval = 0;
  17491. + int *buf = NULL;
  17492. +
  17493. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  17494. + daemonize();
  17495. + spin_lock_irq(&current->sigmask_lock);
  17496. + sigemptyset(&current->blocked);
  17497. + recalc_sigpending(current);
  17498. + spin_unlock_irq(&current->sigmask_lock);
  17499. + sprintf(current->comm, "ocf-random");
  17500. +#else
  17501. + daemonize("ocf-random");
  17502. + allow_signal(SIGKILL);
  17503. +#endif
  17504. +
  17505. + (void) get_fs();
  17506. + set_fs(get_ds());
  17507. +
  17508. +#ifdef CONFIG_OCF_FIPS
  17509. +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
  17510. +#else
  17511. +#define NUM_INT 32
  17512. +#endif
  17513. +
  17514. + /*
  17515. + * some devices can transferr their RNG data direct into memory,
  17516. + * so make sure it is device friendly
  17517. + */
  17518. + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
  17519. + if (NULL == buf) {
  17520. + printk("crypto: RNG could not allocate memory\n");
  17521. + retval = -ENOMEM;
  17522. + goto bad_alloc;
  17523. + }
  17524. +
  17525. + wantcnt = NUM_INT; /* start by adding some entropy */
  17526. +
  17527. + /*
  17528. + * its possible due to errors or driver removal that we no longer
  17529. + * have anything to do, if so exit or we will consume all the CPU
  17530. + * doing nothing
  17531. + */
  17532. + while (!list_empty(&random_ops)) {
  17533. + struct random_op *rops, *tmp;
  17534. +
  17535. +#ifdef CONFIG_OCF_FIPS
  17536. + if (wantcnt)
  17537. + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
  17538. +#endif
  17539. +
  17540. + /* see if we can get enough entropy to make the world
  17541. + * a better place.
  17542. + */
  17543. + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
  17544. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  17545. +
  17546. + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
  17547. + NUM_INT - bufcnt);
  17548. +
  17549. + /* on failure remove the random number generator */
  17550. + if (n == -1) {
  17551. + list_del(&rops->random_list);
  17552. + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
  17553. + rops->driverid);
  17554. + kfree(rops);
  17555. + } else if (n > 0)
  17556. + bufcnt += n;
  17557. + }
  17558. + /* give up CPU for a bit, just in case as this is a loop */
  17559. + schedule();
  17560. + }
  17561. +
  17562. +
  17563. +#ifdef CONFIG_OCF_FIPS
  17564. + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
  17565. + dprintk("crypto: buffer had fips errors, discarding\n");
  17566. + bufcnt = 0;
  17567. + }
  17568. +#endif
  17569. +
  17570. + /*
  17571. + * if we have a certified buffer, we can send some data
  17572. + * to /dev/random and move along
  17573. + */
  17574. + if (bufcnt > 0) {
  17575. + /* add what we have */
  17576. + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
  17577. + bufcnt = 0;
  17578. + }
  17579. +
  17580. + /* give up CPU for a bit so we don't hog while filling */
  17581. + schedule();
  17582. +
  17583. + /* wait for needing more */
  17584. + wantcnt = random_input_wait();
  17585. +
  17586. + if (wantcnt <= 0)
  17587. + wantcnt = 0; /* try to get some info again */
  17588. + else
  17589. + /* round up to one word or we can loop forever */
  17590. + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
  17591. + if (wantcnt > NUM_INT) {
  17592. + wantcnt = NUM_INT;
  17593. + }
  17594. +
  17595. + if (signal_pending(current)) {
  17596. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  17597. + spin_lock_irq(&current->sigmask_lock);
  17598. +#endif
  17599. + flush_signals(current);
  17600. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  17601. + spin_unlock_irq(&current->sigmask_lock);
  17602. +#endif
  17603. + }
  17604. + }
  17605. +
  17606. + kfree(buf);
  17607. +
  17608. +bad_alloc:
  17609. + spin_lock_irq(&random_lock);
  17610. + randomproc = (pid_t) -1;
  17611. + started = 0;
  17612. + spin_unlock_irq(&random_lock);
  17613. +
  17614. + return retval;
  17615. +}
  17616. +
  17617. diff -Nur linux-2.6.29.1.orig/crypto/ocf/rndtest.c linux-2.6.29.1/crypto/ocf/rndtest.c
  17618. --- linux-2.6.29.1.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
  17619. +++ linux-2.6.29.1/crypto/ocf/rndtest.c 2009-04-20 20:01:21.584560546 +0200
  17620. @@ -0,0 +1,300 @@
  17621. +/* $OpenBSD$ */
  17622. +
  17623. +/*
  17624. + * OCF/Linux port done by David McCullough <david_mccullough@securecomputing.com>
  17625. + * Copyright (C) 2006-2007 David McCullough
  17626. + * Copyright (C) 2004-2005 Intel Corporation.
  17627. + * The license and original author are listed below.
  17628. + *
  17629. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  17630. + * All rights reserved.
  17631. + *
  17632. + * Redistribution and use in source and binary forms, with or without
  17633. + * modification, are permitted provided that the following conditions
  17634. + * are met:
  17635. + * 1. Redistributions of source code must retain the above copyright
  17636. + * notice, this list of conditions and the following disclaimer.
  17637. + * 2. Redistributions in binary form must reproduce the above copyright
  17638. + * notice, this list of conditions and the following disclaimer in the
  17639. + * documentation and/or other materials provided with the distribution.
  17640. + * 3. All advertising materials mentioning features or use of this software
  17641. + * must display the following acknowledgement:
  17642. + * This product includes software developed by Jason L. Wright
  17643. + * 4. The name of the author may not be used to endorse or promote products
  17644. + * derived from this software without specific prior written permission.
  17645. + *
  17646. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17647. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17648. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17649. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  17650. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17651. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  17652. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  17653. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  17654. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17655. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17656. + * POSSIBILITY OF SUCH DAMAGE.
  17657. + */
  17658. +
  17659. +#ifndef AUTOCONF_INCLUDED
  17660. +#include <linux/config.h>
  17661. +#endif
  17662. +#include <linux/module.h>
  17663. +#include <linux/list.h>
  17664. +#include <linux/wait.h>
  17665. +#include <linux/time.h>
  17666. +#include <linux/version.h>
  17667. +#include <linux/unistd.h>
  17668. +#include <linux/kernel.h>
  17669. +#include <linux/string.h>
  17670. +#include <linux/time.h>
  17671. +#include <cryptodev.h>
  17672. +#include "rndtest.h"
  17673. +
  17674. +static struct rndtest_stats rndstats;
  17675. +
  17676. +static void rndtest_test(struct rndtest_state *);
  17677. +
  17678. +/* The tests themselves */
  17679. +static int rndtest_monobit(struct rndtest_state *);
  17680. +static int rndtest_runs(struct rndtest_state *);
  17681. +static int rndtest_longruns(struct rndtest_state *);
  17682. +static int rndtest_chi_4(struct rndtest_state *);
  17683. +
  17684. +static int rndtest_runs_check(struct rndtest_state *, int, int *);
  17685. +static void rndtest_runs_record(struct rndtest_state *, int, int *);
  17686. +
  17687. +static const struct rndtest_testfunc {
  17688. + int (*test)(struct rndtest_state *);
  17689. +} rndtest_funcs[] = {
  17690. + { rndtest_monobit },
  17691. + { rndtest_runs },
  17692. + { rndtest_chi_4 },
  17693. + { rndtest_longruns },
  17694. +};
  17695. +
  17696. +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
  17697. +
  17698. +static void
  17699. +rndtest_test(struct rndtest_state *rsp)
  17700. +{
  17701. + int i, rv = 0;
  17702. +
  17703. + rndstats.rst_tests++;
  17704. + for (i = 0; i < RNDTEST_NTESTS; i++)
  17705. + rv |= (*rndtest_funcs[i].test)(rsp);
  17706. + rsp->rs_discard = (rv != 0);
  17707. +}
  17708. +
  17709. +
  17710. +extern int crypto_debug;
  17711. +#define rndtest_verbose 2
  17712. +#define rndtest_report(rsp, failure, fmt, a...) \
  17713. + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
  17714. +
  17715. +#define RNDTEST_MONOBIT_MINONES 9725
  17716. +#define RNDTEST_MONOBIT_MAXONES 10275
  17717. +
  17718. +static int
  17719. +rndtest_monobit(struct rndtest_state *rsp)
  17720. +{
  17721. + int i, ones = 0, j;
  17722. + u_int8_t r;
  17723. +
  17724. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17725. + r = rsp->rs_buf[i];
  17726. + for (j = 0; j < 8; j++, r <<= 1)
  17727. + if (r & 0x80)
  17728. + ones++;
  17729. + }
  17730. + if (ones > RNDTEST_MONOBIT_MINONES &&
  17731. + ones < RNDTEST_MONOBIT_MAXONES) {
  17732. + if (rndtest_verbose > 1)
  17733. + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
  17734. + RNDTEST_MONOBIT_MINONES, ones,
  17735. + RNDTEST_MONOBIT_MAXONES);
  17736. + return (0);
  17737. + } else {
  17738. + if (rndtest_verbose)
  17739. + rndtest_report(rsp, 1,
  17740. + "monobit failed (%d ones)", ones);
  17741. + rndstats.rst_monobit++;
  17742. + return (-1);
  17743. + }
  17744. +}
  17745. +
  17746. +#define RNDTEST_RUNS_NINTERVAL 6
  17747. +
  17748. +static const struct rndtest_runs_tabs {
  17749. + u_int16_t min, max;
  17750. +} rndtest_runs_tab[] = {
  17751. + { 2343, 2657 },
  17752. + { 1135, 1365 },
  17753. + { 542, 708 },
  17754. + { 251, 373 },
  17755. + { 111, 201 },
  17756. + { 111, 201 },
  17757. +};
  17758. +
  17759. +static int
  17760. +rndtest_runs(struct rndtest_state *rsp)
  17761. +{
  17762. + int i, j, ones, zeros, rv = 0;
  17763. + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
  17764. + u_int8_t c;
  17765. +
  17766. + bzero(onei, sizeof(onei));
  17767. + bzero(zeroi, sizeof(zeroi));
  17768. + ones = zeros = 0;
  17769. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17770. + c = rsp->rs_buf[i];
  17771. + for (j = 0; j < 8; j++, c <<= 1) {
  17772. + if (c & 0x80) {
  17773. + ones++;
  17774. + rndtest_runs_record(rsp, zeros, zeroi);
  17775. + zeros = 0;
  17776. + } else {
  17777. + zeros++;
  17778. + rndtest_runs_record(rsp, ones, onei);
  17779. + ones = 0;
  17780. + }
  17781. + }
  17782. + }
  17783. + rndtest_runs_record(rsp, ones, onei);
  17784. + rndtest_runs_record(rsp, zeros, zeroi);
  17785. +
  17786. + rv |= rndtest_runs_check(rsp, 0, zeroi);
  17787. + rv |= rndtest_runs_check(rsp, 1, onei);
  17788. +
  17789. + if (rv)
  17790. + rndstats.rst_runs++;
  17791. +
  17792. + return (rv);
  17793. +}
  17794. +
  17795. +static void
  17796. +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
  17797. +{
  17798. + if (len == 0)
  17799. + return;
  17800. + if (len > RNDTEST_RUNS_NINTERVAL)
  17801. + len = RNDTEST_RUNS_NINTERVAL;
  17802. + len -= 1;
  17803. + intrv[len]++;
  17804. +}
  17805. +
  17806. +static int
  17807. +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
  17808. +{
  17809. + int i, rv = 0;
  17810. +
  17811. + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
  17812. + if (src[i] < rndtest_runs_tab[i].min ||
  17813. + src[i] > rndtest_runs_tab[i].max) {
  17814. + rndtest_report(rsp, 1,
  17815. + "%s interval %d failed (%d, %d-%d)",
  17816. + val ? "ones" : "zeros",
  17817. + i + 1, src[i], rndtest_runs_tab[i].min,
  17818. + rndtest_runs_tab[i].max);
  17819. + rv = -1;
  17820. + } else {
  17821. + rndtest_report(rsp, 0,
  17822. + "runs pass %s interval %d (%d < %d < %d)",
  17823. + val ? "ones" : "zeros",
  17824. + i + 1, rndtest_runs_tab[i].min, src[i],
  17825. + rndtest_runs_tab[i].max);
  17826. + }
  17827. + }
  17828. + return (rv);
  17829. +}
  17830. +
  17831. +static int
  17832. +rndtest_longruns(struct rndtest_state *rsp)
  17833. +{
  17834. + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
  17835. + u_int8_t c;
  17836. +
  17837. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17838. + c = rsp->rs_buf[i];
  17839. + for (j = 0; j < 8; j++, c <<= 1) {
  17840. + if (c & 0x80) {
  17841. + zeros = 0;
  17842. + ones++;
  17843. + if (ones > maxones)
  17844. + maxones = ones;
  17845. + } else {
  17846. + ones = 0;
  17847. + zeros++;
  17848. + if (zeros > maxzeros)
  17849. + maxzeros = zeros;
  17850. + }
  17851. + }
  17852. + }
  17853. +
  17854. + if (maxones < 26 && maxzeros < 26) {
  17855. + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
  17856. + maxones, maxzeros);
  17857. + return (0);
  17858. + } else {
  17859. + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
  17860. + maxones, maxzeros);
  17861. + rndstats.rst_longruns++;
  17862. + return (-1);
  17863. + }
  17864. +}
  17865. +
  17866. +/*
  17867. + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
  17868. + * but it is really the chi^2 test over 4 bits (the poker test as described
  17869. + * by Knuth vol 2 is something different, and I take him as authoritative
  17870. + * on nomenclature over NIST).
  17871. + */
  17872. +#define RNDTEST_CHI4_K 16
  17873. +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
  17874. +
  17875. +/*
  17876. + * The unnormalized values are used so that we don't have to worry about
  17877. + * fractional precision. The "real" value is found by:
  17878. + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
  17879. + */
  17880. +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
  17881. +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
  17882. +
  17883. +static int
  17884. +rndtest_chi_4(struct rndtest_state *rsp)
  17885. +{
  17886. + unsigned int freq[RNDTEST_CHI4_K], i, sum;
  17887. +
  17888. + for (i = 0; i < RNDTEST_CHI4_K; i++)
  17889. + freq[i] = 0;
  17890. +
  17891. + /* Get number of occurances of each 4 bit pattern */
  17892. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  17893. + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
  17894. + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
  17895. + }
  17896. +
  17897. + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
  17898. + sum += freq[i] * freq[i];
  17899. +
  17900. + if (sum >= 1563181 && sum <= 1576929) {
  17901. + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
  17902. + return (0);
  17903. + } else {
  17904. + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
  17905. + rndstats.rst_chi++;
  17906. + return (-1);
  17907. + }
  17908. +}
  17909. +
  17910. +int
  17911. +rndtest_buf(unsigned char *buf)
  17912. +{
  17913. + struct rndtest_state rsp;
  17914. +
  17915. + memset(&rsp, 0, sizeof(rsp));
  17916. + rsp.rs_buf = buf;
  17917. + rndtest_test(&rsp);
  17918. + return(rsp.rs_discard);
  17919. +}
  17920. +
  17921. diff -Nur linux-2.6.29.1.orig/crypto/ocf/rndtest.h linux-2.6.29.1/crypto/ocf/rndtest.h
  17922. --- linux-2.6.29.1.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
  17923. +++ linux-2.6.29.1/crypto/ocf/rndtest.h 2009-04-20 20:01:21.588561893 +0200
  17924. @@ -0,0 +1,54 @@
  17925. +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
  17926. +/* $OpenBSD$ */
  17927. +
  17928. +/*
  17929. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  17930. + * All rights reserved.
  17931. + *
  17932. + * Redistribution and use in source and binary forms, with or without
  17933. + * modification, are permitted provided that the following conditions
  17934. + * are met:
  17935. + * 1. Redistributions of source code must retain the above copyright
  17936. + * notice, this list of conditions and the following disclaimer.
  17937. + * 2. Redistributions in binary form must reproduce the above copyright
  17938. + * notice, this list of conditions and the following disclaimer in the
  17939. + * documentation and/or other materials provided with the distribution.
  17940. + * 3. All advertising materials mentioning features or use of this software
  17941. + * must display the following acknowledgement:
  17942. + * This product includes software developed by Jason L. Wright
  17943. + * 4. The name of the author may not be used to endorse or promote products
  17944. + * derived from this software without specific prior written permission.
  17945. + *
  17946. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17947. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17948. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17949. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  17950. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17951. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  17952. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  17953. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  17954. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17955. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17956. + * POSSIBILITY OF SUCH DAMAGE.
  17957. + */
  17958. +
  17959. +
  17960. +/* Some of the tests depend on these values */
  17961. +#define RNDTEST_NBYTES 2500
  17962. +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
  17963. +
  17964. +struct rndtest_state {
  17965. + int rs_discard; /* discard/accept random data */
  17966. + u_int8_t *rs_buf;
  17967. +};
  17968. +
  17969. +struct rndtest_stats {
  17970. + u_int32_t rst_discard; /* number of bytes discarded */
  17971. + u_int32_t rst_tests; /* number of test runs */
  17972. + u_int32_t rst_monobit; /* monobit test failures */
  17973. + u_int32_t rst_runs; /* 0/1 runs failures */
  17974. + u_int32_t rst_longruns; /* longruns failures */
  17975. + u_int32_t rst_chi; /* chi^2 failures */
  17976. +};
  17977. +
  17978. +extern int rndtest_buf(unsigned char *buf);
  17979. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/Makefile linux-2.6.29.1/crypto/ocf/safe/Makefile
  17980. --- linux-2.6.29.1.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
  17981. +++ linux-2.6.29.1/crypto/ocf/safe/Makefile 2009-04-20 20:01:21.588561893 +0200
  17982. @@ -0,0 +1,12 @@
  17983. +# for SGlinux builds
  17984. +-include $(ROOTDIR)/modules/.config
  17985. +
  17986. +obj-$(CONFIG_OCF_SAFE) += safe.o
  17987. +
  17988. +obj ?= .
  17989. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  17990. +
  17991. +ifdef TOPDIR
  17992. +-include $(TOPDIR)/Rules.make
  17993. +endif
  17994. +
  17995. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/md5.c linux-2.6.29.1/crypto/ocf/safe/md5.c
  17996. --- linux-2.6.29.1.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
  17997. +++ linux-2.6.29.1/crypto/ocf/safe/md5.c 2009-04-20 20:01:21.588561893 +0200
  17998. @@ -0,0 +1,308 @@
  17999. +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  18000. +/*
  18001. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  18002. + * All rights reserved.
  18003. + *
  18004. + * Redistribution and use in source and binary forms, with or without
  18005. + * modification, are permitted provided that the following conditions
  18006. + * are met:
  18007. + * 1. Redistributions of source code must retain the above copyright
  18008. + * notice, this list of conditions and the following disclaimer.
  18009. + * 2. Redistributions in binary form must reproduce the above copyright
  18010. + * notice, this list of conditions and the following disclaimer in the
  18011. + * documentation and/or other materials provided with the distribution.
  18012. + * 3. Neither the name of the project nor the names of its contributors
  18013. + * may be used to endorse or promote products derived from this software
  18014. + * without specific prior written permission.
  18015. + *
  18016. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  18017. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18018. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18019. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  18020. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18021. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  18022. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  18023. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18024. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  18025. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  18026. + * SUCH DAMAGE.
  18027. + */
  18028. +
  18029. +#if 0
  18030. +#include <sys/cdefs.h>
  18031. +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
  18032. +
  18033. +#include <sys/types.h>
  18034. +#include <sys/cdefs.h>
  18035. +#include <sys/time.h>
  18036. +#include <sys/systm.h>
  18037. +#include <crypto/md5.h>
  18038. +#endif
  18039. +
  18040. +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
  18041. +
  18042. +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
  18043. +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
  18044. +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
  18045. +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
  18046. +
  18047. +#define ROUND1(a, b, c, d, k, s, i) { \
  18048. + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
  18049. + (a) = SHIFT((a), (s)); \
  18050. + (a) = (b) + (a); \
  18051. +}
  18052. +
  18053. +#define ROUND2(a, b, c, d, k, s, i) { \
  18054. + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
  18055. + (a) = SHIFT((a), (s)); \
  18056. + (a) = (b) + (a); \
  18057. +}
  18058. +
  18059. +#define ROUND3(a, b, c, d, k, s, i) { \
  18060. + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
  18061. + (a) = SHIFT((a), (s)); \
  18062. + (a) = (b) + (a); \
  18063. +}
  18064. +
  18065. +#define ROUND4(a, b, c, d, k, s, i) { \
  18066. + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
  18067. + (a) = SHIFT((a), (s)); \
  18068. + (a) = (b) + (a); \
  18069. +}
  18070. +
  18071. +#define Sa 7
  18072. +#define Sb 12
  18073. +#define Sc 17
  18074. +#define Sd 22
  18075. +
  18076. +#define Se 5
  18077. +#define Sf 9
  18078. +#define Sg 14
  18079. +#define Sh 20
  18080. +
  18081. +#define Si 4
  18082. +#define Sj 11
  18083. +#define Sk 16
  18084. +#define Sl 23
  18085. +
  18086. +#define Sm 6
  18087. +#define Sn 10
  18088. +#define So 15
  18089. +#define Sp 21
  18090. +
  18091. +#define MD5_A0 0x67452301
  18092. +#define MD5_B0 0xefcdab89
  18093. +#define MD5_C0 0x98badcfe
  18094. +#define MD5_D0 0x10325476
  18095. +
  18096. +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
  18097. +static const u_int32_t T[65] = {
  18098. + 0,
  18099. + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  18100. + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  18101. + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  18102. + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  18103. +
  18104. + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  18105. + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
  18106. + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  18107. + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  18108. +
  18109. + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  18110. + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  18111. + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
  18112. + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  18113. +
  18114. + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  18115. + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  18116. + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  18117. + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  18118. +};
  18119. +
  18120. +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  18121. + 0x80, 0, 0, 0, 0, 0, 0, 0,
  18122. + 0, 0, 0, 0, 0, 0, 0, 0,
  18123. + 0, 0, 0, 0, 0, 0, 0, 0,
  18124. + 0, 0, 0, 0, 0, 0, 0, 0,
  18125. + 0, 0, 0, 0, 0, 0, 0, 0,
  18126. + 0, 0, 0, 0, 0, 0, 0, 0,
  18127. + 0, 0, 0, 0, 0, 0, 0, 0,
  18128. + 0, 0, 0, 0, 0, 0, 0, 0,
  18129. +};
  18130. +
  18131. +static void md5_calc(u_int8_t *, md5_ctxt *);
  18132. +
  18133. +void md5_init(ctxt)
  18134. + md5_ctxt *ctxt;
  18135. +{
  18136. + ctxt->md5_n = 0;
  18137. + ctxt->md5_i = 0;
  18138. + ctxt->md5_sta = MD5_A0;
  18139. + ctxt->md5_stb = MD5_B0;
  18140. + ctxt->md5_stc = MD5_C0;
  18141. + ctxt->md5_std = MD5_D0;
  18142. + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  18143. +}
  18144. +
  18145. +void md5_loop(ctxt, input, len)
  18146. + md5_ctxt *ctxt;
  18147. + u_int8_t *input;
  18148. + u_int len; /* number of bytes */
  18149. +{
  18150. + u_int gap, i;
  18151. +
  18152. + ctxt->md5_n += len * 8; /* byte to bit */
  18153. + gap = MD5_BUFLEN - ctxt->md5_i;
  18154. +
  18155. + if (len >= gap) {
  18156. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  18157. + gap);
  18158. + md5_calc(ctxt->md5_buf, ctxt);
  18159. +
  18160. + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  18161. + md5_calc((u_int8_t *)(input + i), ctxt);
  18162. + }
  18163. +
  18164. + ctxt->md5_i = len - i;
  18165. + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  18166. + } else {
  18167. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  18168. + len);
  18169. + ctxt->md5_i += len;
  18170. + }
  18171. +}
  18172. +
  18173. +void md5_pad(ctxt)
  18174. + md5_ctxt *ctxt;
  18175. +{
  18176. + u_int gap;
  18177. +
  18178. + /* Don't count up padding. Keep md5_n. */
  18179. + gap = MD5_BUFLEN - ctxt->md5_i;
  18180. + if (gap > 8) {
  18181. + bcopy(md5_paddat,
  18182. + (void *)(ctxt->md5_buf + ctxt->md5_i),
  18183. + gap - sizeof(ctxt->md5_n));
  18184. + } else {
  18185. + /* including gap == 8 */
  18186. + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  18187. + gap);
  18188. + md5_calc(ctxt->md5_buf, ctxt);
  18189. + bcopy((md5_paddat + gap),
  18190. + (void *)ctxt->md5_buf,
  18191. + MD5_BUFLEN - sizeof(ctxt->md5_n));
  18192. + }
  18193. +
  18194. + /* 8 byte word */
  18195. +#if BYTE_ORDER == LITTLE_ENDIAN
  18196. + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  18197. +#endif
  18198. +#if BYTE_ORDER == BIG_ENDIAN
  18199. + ctxt->md5_buf[56] = ctxt->md5_n8[7];
  18200. + ctxt->md5_buf[57] = ctxt->md5_n8[6];
  18201. + ctxt->md5_buf[58] = ctxt->md5_n8[5];
  18202. + ctxt->md5_buf[59] = ctxt->md5_n8[4];
  18203. + ctxt->md5_buf[60] = ctxt->md5_n8[3];
  18204. + ctxt->md5_buf[61] = ctxt->md5_n8[2];
  18205. + ctxt->md5_buf[62] = ctxt->md5_n8[1];
  18206. + ctxt->md5_buf[63] = ctxt->md5_n8[0];
  18207. +#endif
  18208. +
  18209. + md5_calc(ctxt->md5_buf, ctxt);
  18210. +}
  18211. +
  18212. +void md5_result(digest, ctxt)
  18213. + u_int8_t *digest;
  18214. + md5_ctxt *ctxt;
  18215. +{
  18216. + /* 4 byte words */
  18217. +#if BYTE_ORDER == LITTLE_ENDIAN
  18218. + bcopy(&ctxt->md5_st8[0], digest, 16);
  18219. +#endif
  18220. +#if BYTE_ORDER == BIG_ENDIAN
  18221. + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  18222. + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  18223. + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  18224. + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  18225. + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  18226. + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  18227. + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  18228. + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  18229. +#endif
  18230. +}
  18231. +
  18232. +static void md5_calc(b64, ctxt)
  18233. + u_int8_t *b64;
  18234. + md5_ctxt *ctxt;
  18235. +{
  18236. + u_int32_t A = ctxt->md5_sta;
  18237. + u_int32_t B = ctxt->md5_stb;
  18238. + u_int32_t C = ctxt->md5_stc;
  18239. + u_int32_t D = ctxt->md5_std;
  18240. +#if BYTE_ORDER == LITTLE_ENDIAN
  18241. + u_int32_t *X = (u_int32_t *)b64;
  18242. +#endif
  18243. +#if BYTE_ORDER == BIG_ENDIAN
  18244. + /* 4 byte words */
  18245. + /* what a brute force but fast! */
  18246. + u_int32_t X[16];
  18247. + u_int8_t *y = (u_int8_t *)X;
  18248. + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  18249. + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  18250. + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  18251. + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  18252. + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  18253. + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  18254. + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  18255. + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  18256. + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  18257. + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  18258. + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  18259. + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  18260. + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  18261. + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  18262. + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  18263. + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  18264. +#endif
  18265. +
  18266. + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
  18267. + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
  18268. + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
  18269. + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
  18270. + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
  18271. + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  18272. + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  18273. + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  18274. +
  18275. + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
  18276. + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
  18277. + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  18278. + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
  18279. + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  18280. + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
  18281. + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
  18282. + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  18283. +
  18284. + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
  18285. + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  18286. + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
  18287. + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  18288. + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
  18289. + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
  18290. + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  18291. + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
  18292. +
  18293. + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
  18294. + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
  18295. + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
  18296. + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
  18297. + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
  18298. + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
  18299. + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
  18300. + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
  18301. +
  18302. + ctxt->md5_sta += A;
  18303. + ctxt->md5_stb += B;
  18304. + ctxt->md5_stc += C;
  18305. + ctxt->md5_std += D;
  18306. +}
  18307. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/md5.h linux-2.6.29.1/crypto/ocf/safe/md5.h
  18308. --- linux-2.6.29.1.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
  18309. +++ linux-2.6.29.1/crypto/ocf/safe/md5.h 2009-04-20 20:01:21.588561893 +0200
  18310. @@ -0,0 +1,76 @@
  18311. +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
  18312. +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
  18313. +
  18314. +/*
  18315. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  18316. + * All rights reserved.
  18317. + *
  18318. + * Redistribution and use in source and binary forms, with or without
  18319. + * modification, are permitted provided that the following conditions
  18320. + * are met:
  18321. + * 1. Redistributions of source code must retain the above copyright
  18322. + * notice, this list of conditions and the following disclaimer.
  18323. + * 2. Redistributions in binary form must reproduce the above copyright
  18324. + * notice, this list of conditions and the following disclaimer in the
  18325. + * documentation and/or other materials provided with the distribution.
  18326. + * 3. Neither the name of the project nor the names of its contributors
  18327. + * may be used to endorse or promote products derived from this software
  18328. + * without specific prior written permission.
  18329. + *
  18330. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  18331. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18332. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18333. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  18334. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18335. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  18336. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  18337. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18338. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  18339. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  18340. + * SUCH DAMAGE.
  18341. + */
  18342. +
  18343. +#ifndef _NETINET6_MD5_H_
  18344. +#define _NETINET6_MD5_H_
  18345. +
  18346. +#define MD5_BUFLEN 64
  18347. +
  18348. +typedef struct {
  18349. + union {
  18350. + u_int32_t md5_state32[4];
  18351. + u_int8_t md5_state8[16];
  18352. + } md5_st;
  18353. +
  18354. +#define md5_sta md5_st.md5_state32[0]
  18355. +#define md5_stb md5_st.md5_state32[1]
  18356. +#define md5_stc md5_st.md5_state32[2]
  18357. +#define md5_std md5_st.md5_state32[3]
  18358. +#define md5_st8 md5_st.md5_state8
  18359. +
  18360. + union {
  18361. + u_int64_t md5_count64;
  18362. + u_int8_t md5_count8[8];
  18363. + } md5_count;
  18364. +#define md5_n md5_count.md5_count64
  18365. +#define md5_n8 md5_count.md5_count8
  18366. +
  18367. + u_int md5_i;
  18368. + u_int8_t md5_buf[MD5_BUFLEN];
  18369. +} md5_ctxt;
  18370. +
  18371. +extern void md5_init(md5_ctxt *);
  18372. +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
  18373. +extern void md5_pad(md5_ctxt *);
  18374. +extern void md5_result(u_int8_t *, md5_ctxt *);
  18375. +
  18376. +/* compatibility */
  18377. +#define MD5_CTX md5_ctxt
  18378. +#define MD5Init(x) md5_init((x))
  18379. +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
  18380. +#define MD5Final(x, y) \
  18381. +do { \
  18382. + md5_pad((y)); \
  18383. + md5_result((x), (y)); \
  18384. +} while (0)
  18385. +
  18386. +#endif /* ! _NETINET6_MD5_H_*/
  18387. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/safe.c linux-2.6.29.1/crypto/ocf/safe/safe.c
  18388. --- linux-2.6.29.1.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
  18389. +++ linux-2.6.29.1/crypto/ocf/safe/safe.c 2009-04-20 20:01:21.596561515 +0200
  18390. @@ -0,0 +1,2288 @@
  18391. +/*-
  18392. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  18393. + * Copyright (C) 2004-2007 David McCullough
  18394. + * The license and original author are listed below.
  18395. + *
  18396. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  18397. + * Copyright (c) 2003 Global Technology Associates, Inc.
  18398. + * All rights reserved.
  18399. + *
  18400. + * Redistribution and use in source and binary forms, with or without
  18401. + * modification, are permitted provided that the following conditions
  18402. + * are met:
  18403. + * 1. Redistributions of source code must retain the above copyright
  18404. + * notice, this list of conditions and the following disclaimer.
  18405. + * 2. Redistributions in binary form must reproduce the above copyright
  18406. + * notice, this list of conditions and the following disclaimer in the
  18407. + * documentation and/or other materials provided with the distribution.
  18408. + *
  18409. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18410. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18411. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18412. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18413. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18414. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  18415. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  18416. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  18417. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  18418. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  18419. + * SUCH DAMAGE.
  18420. + *
  18421. +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
  18422. + */
  18423. +
  18424. +#ifndef AUTOCONF_INCLUDED
  18425. +#include <linux/config.h>
  18426. +#endif
  18427. +#include <linux/module.h>
  18428. +#include <linux/kernel.h>
  18429. +#include <linux/init.h>
  18430. +#include <linux/list.h>
  18431. +#include <linux/slab.h>
  18432. +#include <linux/wait.h>
  18433. +#include <linux/sched.h>
  18434. +#include <linux/pci.h>
  18435. +#include <linux/delay.h>
  18436. +#include <linux/interrupt.h>
  18437. +#include <linux/spinlock.h>
  18438. +#include <linux/random.h>
  18439. +#include <linux/version.h>
  18440. +#include <linux/skbuff.h>
  18441. +#include <asm/io.h>
  18442. +
  18443. +/*
  18444. + * SafeNet SafeXcel-1141 hardware crypto accelerator
  18445. + */
  18446. +
  18447. +#include <cryptodev.h>
  18448. +#include <uio.h>
  18449. +#include <safe/safereg.h>
  18450. +#include <safe/safevar.h>
  18451. +
  18452. +#if 1
  18453. +#define DPRINTF(a) do { \
  18454. + if (debug) { \
  18455. + printk("%s: ", sc ? \
  18456. + device_get_nameunit(sc->sc_dev) : "safe"); \
  18457. + printk a; \
  18458. + } \
  18459. + } while (0)
  18460. +#else
  18461. +#define DPRINTF(a)
  18462. +#endif
  18463. +
  18464. +/*
  18465. + * until we find a cleaner way, include the BSD md5/sha1 code
  18466. + * here
  18467. + */
  18468. +#define HMAC_HACK 1
  18469. +#ifdef HMAC_HACK
  18470. +#define LITTLE_ENDIAN 1234
  18471. +#define BIG_ENDIAN 4321
  18472. +#ifdef __LITTLE_ENDIAN
  18473. +#define BYTE_ORDER LITTLE_ENDIAN
  18474. +#endif
  18475. +#ifdef __BIG_ENDIAN
  18476. +#define BYTE_ORDER BIG_ENDIAN
  18477. +#endif
  18478. +#include <safe/md5.h>
  18479. +#include <safe/md5.c>
  18480. +#include <safe/sha1.h>
  18481. +#include <safe/sha1.c>
  18482. +
  18483. +u_int8_t hmac_ipad_buffer[64] = {
  18484. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18485. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18486. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18487. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18488. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18489. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18490. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  18491. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
  18492. +};
  18493. +
  18494. +u_int8_t hmac_opad_buffer[64] = {
  18495. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18496. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18497. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18498. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18499. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18500. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18501. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  18502. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
  18503. +};
  18504. +#endif /* HMAC_HACK */
  18505. +
  18506. +/* add proc entry for this */
  18507. +struct safe_stats safestats;
  18508. +
  18509. +#define debug safe_debug
  18510. +int safe_debug = 0;
  18511. +module_param(safe_debug, int, 0644);
  18512. +MODULE_PARM_DESC(safe_debug, "Enable debug");
  18513. +
  18514. +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
  18515. +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
  18516. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  18517. +static void safe_rng_init(struct safe_softc *);
  18518. +int safe_rngbufsize = 8; /* 32 bytes each read */
  18519. +module_param(safe_rngbufsize, int, 0644);
  18520. +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
  18521. +int safe_rngmaxalarm = 8; /* max alarms before reset */
  18522. +module_param(safe_rngmaxalarm, int, 0644);
  18523. +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
  18524. +#endif /* SAFE_NO_RNG */
  18525. +
  18526. +static void safe_totalreset(struct safe_softc *sc);
  18527. +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
  18528. +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
  18529. +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
  18530. +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
  18531. +static int safe_kstart(struct safe_softc *sc);
  18532. +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
  18533. +static void safe_kfeed(struct safe_softc *sc);
  18534. +static void safe_kpoll(unsigned long arg);
  18535. +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
  18536. + u_int32_t len, struct crparam *n);
  18537. +
  18538. +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
  18539. +static int safe_freesession(device_t, u_int64_t);
  18540. +static int safe_process(device_t, struct cryptop *, int);
  18541. +
  18542. +static device_method_t safe_methods = {
  18543. + /* crypto device methods */
  18544. + DEVMETHOD(cryptodev_newsession, safe_newsession),
  18545. + DEVMETHOD(cryptodev_freesession,safe_freesession),
  18546. + DEVMETHOD(cryptodev_process, safe_process),
  18547. + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
  18548. +};
  18549. +
  18550. +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
  18551. +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
  18552. +
  18553. +#define SAFE_MAX_CHIPS 8
  18554. +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
  18555. +
  18556. +/*
  18557. + * split our buffers up into safe DMAable byte fragments to avoid lockup
  18558. + * bug in 1141 HW on rev 1.0.
  18559. + */
  18560. +
  18561. +static int
  18562. +pci_map_linear(
  18563. + struct safe_softc *sc,
  18564. + struct safe_operand *buf,
  18565. + void *addr,
  18566. + int len)
  18567. +{
  18568. + dma_addr_t tmp;
  18569. + int chunk, tlen = len;
  18570. +
  18571. + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
  18572. +
  18573. + buf->mapsize += len;
  18574. + while (len > 0) {
  18575. + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
  18576. + buf->segs[buf->nsegs].ds_addr = tmp;
  18577. + buf->segs[buf->nsegs].ds_len = chunk;
  18578. + buf->segs[buf->nsegs].ds_tlen = tlen;
  18579. + buf->nsegs++;
  18580. + tmp += chunk;
  18581. + len -= chunk;
  18582. + tlen = 0;
  18583. + }
  18584. + return 0;
  18585. +}
  18586. +
  18587. +/*
  18588. + * map in a given uio buffer (great on some arches :-)
  18589. + */
  18590. +
  18591. +static int
  18592. +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
  18593. +{
  18594. + struct iovec *iov = uio->uio_iov;
  18595. + int n;
  18596. +
  18597. + DPRINTF(("%s()\n", __FUNCTION__));
  18598. +
  18599. + buf->mapsize = 0;
  18600. + buf->nsegs = 0;
  18601. +
  18602. + for (n = 0; n < uio->uio_iovcnt; n++) {
  18603. + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
  18604. + iov++;
  18605. + }
  18606. +
  18607. + /* identify this buffer by the first segment */
  18608. + buf->map = (void *) buf->segs[0].ds_addr;
  18609. + return(0);
  18610. +}
  18611. +
  18612. +/*
  18613. + * map in a given sk_buff
  18614. + */
  18615. +
  18616. +static int
  18617. +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
  18618. +{
  18619. + int i;
  18620. +
  18621. + DPRINTF(("%s()\n", __FUNCTION__));
  18622. +
  18623. + buf->mapsize = 0;
  18624. + buf->nsegs = 0;
  18625. +
  18626. + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
  18627. +
  18628. + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
  18629. + pci_map_linear(sc, buf,
  18630. + page_address(skb_shinfo(skb)->frags[i].page) +
  18631. + skb_shinfo(skb)->frags[i].page_offset,
  18632. + skb_shinfo(skb)->frags[i].size);
  18633. + }
  18634. +
  18635. + /* identify this buffer by the first segment */
  18636. + buf->map = (void *) buf->segs[0].ds_addr;
  18637. + return(0);
  18638. +}
  18639. +
  18640. +
  18641. +#if 0 /* not needed at this time */
  18642. +static void
  18643. +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
  18644. +{
  18645. + int i;
  18646. +
  18647. + DPRINTF(("%s()\n", __FUNCTION__));
  18648. + for (i = 0; i < buf->nsegs; i++)
  18649. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  18650. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  18651. +}
  18652. +#endif
  18653. +
  18654. +static void
  18655. +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
  18656. +{
  18657. + int i;
  18658. + DPRINTF(("%s()\n", __FUNCTION__));
  18659. + for (i = 0; i < buf->nsegs; i++) {
  18660. + if (buf->segs[i].ds_tlen) {
  18661. + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  18662. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  18663. + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
  18664. + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  18665. + }
  18666. + buf->segs[i].ds_addr = 0;
  18667. + buf->segs[i].ds_len = 0;
  18668. + buf->segs[i].ds_tlen = 0;
  18669. + }
  18670. + buf->nsegs = 0;
  18671. + buf->mapsize = 0;
  18672. + buf->map = 0;
  18673. +}
  18674. +
  18675. +
  18676. +/*
  18677. + * SafeXcel Interrupt routine
  18678. + */
  18679. +static irqreturn_t
  18680. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  18681. +safe_intr(int irq, void *arg)
  18682. +#else
  18683. +safe_intr(int irq, void *arg, struct pt_regs *regs)
  18684. +#endif
  18685. +{
  18686. + struct safe_softc *sc = arg;
  18687. + int stat;
  18688. + unsigned long flags;
  18689. +
  18690. + stat = READ_REG(sc, SAFE_HM_STAT);
  18691. +
  18692. + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
  18693. +
  18694. + if (stat == 0) /* shared irq, not for us */
  18695. + return IRQ_NONE;
  18696. +
  18697. + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
  18698. +
  18699. + if ((stat & SAFE_INT_PE_DDONE)) {
  18700. + /*
  18701. + * Descriptor(s) done; scan the ring and
  18702. + * process completed operations.
  18703. + */
  18704. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  18705. + while (sc->sc_back != sc->sc_front) {
  18706. + struct safe_ringentry *re = sc->sc_back;
  18707. +
  18708. +#ifdef SAFE_DEBUG
  18709. + if (debug) {
  18710. + safe_dump_ringstate(sc, __func__);
  18711. + safe_dump_request(sc, __func__, re);
  18712. + }
  18713. +#endif
  18714. + /*
  18715. + * safe_process marks ring entries that were allocated
  18716. + * but not used with a csr of zero. This insures the
  18717. + * ring front pointer never needs to be set backwards
  18718. + * in the event that an entry is allocated but not used
  18719. + * because of a setup error.
  18720. + */
  18721. + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
  18722. + if (re->re_desc.d_csr != 0) {
  18723. + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
  18724. + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
  18725. + break;
  18726. + }
  18727. + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
  18728. + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
  18729. + break;
  18730. + }
  18731. + sc->sc_nqchip--;
  18732. + safe_callback(sc, re);
  18733. + }
  18734. + if (++(sc->sc_back) == sc->sc_ringtop)
  18735. + sc->sc_back = sc->sc_ring;
  18736. + }
  18737. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  18738. + }
  18739. +
  18740. + /*
  18741. + * Check to see if we got any DMA Error
  18742. + */
  18743. + if (stat & SAFE_INT_PE_ERROR) {
  18744. + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
  18745. + (int)READ_REG(sc, SAFE_PE_DMASTAT));
  18746. + safestats.st_dmaerr++;
  18747. + safe_totalreset(sc);
  18748. +#if 0
  18749. + safe_feed(sc);
  18750. +#endif
  18751. + }
  18752. +
  18753. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  18754. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  18755. + DPRINTF(("%s: wakeup crypto %x\n", __func__,
  18756. + sc->sc_needwakeup));
  18757. + sc->sc_needwakeup &= ~wakeup;
  18758. + crypto_unblock(sc->sc_cid, wakeup);
  18759. + }
  18760. +
  18761. + return IRQ_HANDLED;
  18762. +}
  18763. +
  18764. +/*
  18765. + * safe_feed() - post a request to chip
  18766. + */
  18767. +static void
  18768. +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
  18769. +{
  18770. + DPRINTF(("%s()\n", __FUNCTION__));
  18771. +#ifdef SAFE_DEBUG
  18772. + if (debug) {
  18773. + safe_dump_ringstate(sc, __func__);
  18774. + safe_dump_request(sc, __func__, re);
  18775. + }
  18776. +#endif
  18777. + sc->sc_nqchip++;
  18778. + if (sc->sc_nqchip > safestats.st_maxqchip)
  18779. + safestats.st_maxqchip = sc->sc_nqchip;
  18780. + /* poke h/w to check descriptor ring, any value can be written */
  18781. + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
  18782. +}
  18783. +
  18784. +#define N(a) (sizeof(a) / sizeof (a[0]))
  18785. +static void
  18786. +safe_setup_enckey(struct safe_session *ses, caddr_t key)
  18787. +{
  18788. + int i;
  18789. +
  18790. + bcopy(key, ses->ses_key, ses->ses_klen / 8);
  18791. +
  18792. + /* PE is little-endian, insure proper byte order */
  18793. + for (i = 0; i < N(ses->ses_key); i++)
  18794. + ses->ses_key[i] = htole32(ses->ses_key[i]);
  18795. +}
  18796. +
  18797. +static void
  18798. +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
  18799. +{
  18800. +#ifdef HMAC_HACK
  18801. + MD5_CTX md5ctx;
  18802. + SHA1_CTX sha1ctx;
  18803. + int i;
  18804. +
  18805. +
  18806. + for (i = 0; i < klen; i++)
  18807. + key[i] ^= HMAC_IPAD_VAL;
  18808. +
  18809. + if (algo == CRYPTO_MD5_HMAC) {
  18810. + MD5Init(&md5ctx);
  18811. + MD5Update(&md5ctx, key, klen);
  18812. + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  18813. + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
  18814. + } else {
  18815. + SHA1Init(&sha1ctx);
  18816. + SHA1Update(&sha1ctx, key, klen);
  18817. + SHA1Update(&sha1ctx, hmac_ipad_buffer,
  18818. + SHA1_HMAC_BLOCK_LEN - klen);
  18819. + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
  18820. + }
  18821. +
  18822. + for (i = 0; i < klen; i++)
  18823. + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  18824. +
  18825. + if (algo == CRYPTO_MD5_HMAC) {
  18826. + MD5Init(&md5ctx);
  18827. + MD5Update(&md5ctx, key, klen);
  18828. + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  18829. + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
  18830. + } else {
  18831. + SHA1Init(&sha1ctx);
  18832. + SHA1Update(&sha1ctx, key, klen);
  18833. + SHA1Update(&sha1ctx, hmac_opad_buffer,
  18834. + SHA1_HMAC_BLOCK_LEN - klen);
  18835. + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
  18836. + }
  18837. +
  18838. + for (i = 0; i < klen; i++)
  18839. + key[i] ^= HMAC_OPAD_VAL;
  18840. +
  18841. +#if 0
  18842. + /*
  18843. + * this code prevents SHA working on a BE host,
  18844. + * so it is obviously wrong. I think the byte
  18845. + * swap setup we do with the chip fixes this for us
  18846. + */
  18847. +
  18848. + /* PE is little-endian, insure proper byte order */
  18849. + for (i = 0; i < N(ses->ses_hminner); i++) {
  18850. + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
  18851. + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
  18852. + }
  18853. +#endif
  18854. +#else /* HMAC_HACK */
  18855. + printk("safe: md5/sha not implemented\n");
  18856. +#endif /* HMAC_HACK */
  18857. +}
  18858. +#undef N
  18859. +
  18860. +/*
  18861. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  18862. + * contains our registration id, and should contain an encoded session
  18863. + * id on successful allocation.
  18864. + */
  18865. +static int
  18866. +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  18867. +{
  18868. + struct safe_softc *sc = device_get_softc(dev);
  18869. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  18870. + struct safe_session *ses = NULL;
  18871. + int sesn;
  18872. +
  18873. + DPRINTF(("%s()\n", __FUNCTION__));
  18874. +
  18875. + if (sidp == NULL || cri == NULL || sc == NULL)
  18876. + return (EINVAL);
  18877. +
  18878. + for (c = cri; c != NULL; c = c->cri_next) {
  18879. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  18880. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  18881. + c->cri_alg == CRYPTO_NULL_HMAC) {
  18882. + if (macini)
  18883. + return (EINVAL);
  18884. + macini = c;
  18885. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  18886. + c->cri_alg == CRYPTO_3DES_CBC ||
  18887. + c->cri_alg == CRYPTO_AES_CBC ||
  18888. + c->cri_alg == CRYPTO_NULL_CBC) {
  18889. + if (encini)
  18890. + return (EINVAL);
  18891. + encini = c;
  18892. + } else
  18893. + return (EINVAL);
  18894. + }
  18895. + if (encini == NULL && macini == NULL)
  18896. + return (EINVAL);
  18897. + if (encini) { /* validate key length */
  18898. + switch (encini->cri_alg) {
  18899. + case CRYPTO_DES_CBC:
  18900. + if (encini->cri_klen != 64)
  18901. + return (EINVAL);
  18902. + break;
  18903. + case CRYPTO_3DES_CBC:
  18904. + if (encini->cri_klen != 192)
  18905. + return (EINVAL);
  18906. + break;
  18907. + case CRYPTO_AES_CBC:
  18908. + if (encini->cri_klen != 128 &&
  18909. + encini->cri_klen != 192 &&
  18910. + encini->cri_klen != 256)
  18911. + return (EINVAL);
  18912. + break;
  18913. + }
  18914. + }
  18915. +
  18916. + if (sc->sc_sessions == NULL) {
  18917. + ses = sc->sc_sessions = (struct safe_session *)
  18918. + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
  18919. + if (ses == NULL)
  18920. + return (ENOMEM);
  18921. + memset(ses, 0, sizeof(struct safe_session));
  18922. + sesn = 0;
  18923. + sc->sc_nsessions = 1;
  18924. + } else {
  18925. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  18926. + if (sc->sc_sessions[sesn].ses_used == 0) {
  18927. + ses = &sc->sc_sessions[sesn];
  18928. + break;
  18929. + }
  18930. + }
  18931. +
  18932. + if (ses == NULL) {
  18933. + sesn = sc->sc_nsessions;
  18934. + ses = (struct safe_session *)
  18935. + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
  18936. + if (ses == NULL)
  18937. + return (ENOMEM);
  18938. + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
  18939. + bcopy(sc->sc_sessions, ses, sesn *
  18940. + sizeof(struct safe_session));
  18941. + bzero(sc->sc_sessions, sesn *
  18942. + sizeof(struct safe_session));
  18943. + kfree(sc->sc_sessions);
  18944. + sc->sc_sessions = ses;
  18945. + ses = &sc->sc_sessions[sesn];
  18946. + sc->sc_nsessions++;
  18947. + }
  18948. + }
  18949. +
  18950. + bzero(ses, sizeof(struct safe_session));
  18951. + ses->ses_used = 1;
  18952. +
  18953. + if (encini) {
  18954. + /* get an IV */
  18955. + /* XXX may read fewer than requested */
  18956. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  18957. +
  18958. + ses->ses_klen = encini->cri_klen;
  18959. + if (encini->cri_key != NULL)
  18960. + safe_setup_enckey(ses, encini->cri_key);
  18961. + }
  18962. +
  18963. + if (macini) {
  18964. + ses->ses_mlen = macini->cri_mlen;
  18965. + if (ses->ses_mlen == 0) {
  18966. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  18967. + ses->ses_mlen = MD5_HASH_LEN;
  18968. + else
  18969. + ses->ses_mlen = SHA1_HASH_LEN;
  18970. + }
  18971. +
  18972. + if (macini->cri_key != NULL) {
  18973. + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
  18974. + macini->cri_klen / 8);
  18975. + }
  18976. + }
  18977. +
  18978. + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
  18979. + return (0);
  18980. +}
  18981. +
  18982. +/*
  18983. + * Deallocate a session.
  18984. + */
  18985. +static int
  18986. +safe_freesession(device_t dev, u_int64_t tid)
  18987. +{
  18988. + struct safe_softc *sc = device_get_softc(dev);
  18989. + int session, ret;
  18990. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  18991. +
  18992. + DPRINTF(("%s()\n", __FUNCTION__));
  18993. +
  18994. + if (sc == NULL)
  18995. + return (EINVAL);
  18996. +
  18997. + session = SAFE_SESSION(sid);
  18998. + if (session < sc->sc_nsessions) {
  18999. + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
  19000. + ret = 0;
  19001. + } else
  19002. + ret = EINVAL;
  19003. + return (ret);
  19004. +}
  19005. +
  19006. +
  19007. +static int
  19008. +safe_process(device_t dev, struct cryptop *crp, int hint)
  19009. +{
  19010. + struct safe_softc *sc = device_get_softc(dev);
  19011. + int err = 0, i, nicealign, uniform;
  19012. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  19013. + int bypass, oplen, ivsize;
  19014. + caddr_t iv;
  19015. + int16_t coffset;
  19016. + struct safe_session *ses;
  19017. + struct safe_ringentry *re;
  19018. + struct safe_sarec *sa;
  19019. + struct safe_pdesc *pd;
  19020. + u_int32_t cmd0, cmd1, staterec;
  19021. + unsigned long flags;
  19022. +
  19023. + DPRINTF(("%s()\n", __FUNCTION__));
  19024. +
  19025. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  19026. + safestats.st_invalid++;
  19027. + return (EINVAL);
  19028. + }
  19029. + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  19030. + safestats.st_badsession++;
  19031. + return (EINVAL);
  19032. + }
  19033. +
  19034. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  19035. + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
  19036. + safestats.st_ringfull++;
  19037. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  19038. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  19039. + return (ERESTART);
  19040. + }
  19041. + re = sc->sc_front;
  19042. +
  19043. + staterec = re->re_sa.sa_staterec; /* save */
  19044. + /* NB: zero everything but the PE descriptor */
  19045. + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
  19046. + re->re_sa.sa_staterec = staterec; /* restore */
  19047. +
  19048. + re->re_crp = crp;
  19049. + re->re_sesn = SAFE_SESSION(crp->crp_sid);
  19050. +
  19051. + re->re_src.nsegs = 0;
  19052. + re->re_dst.nsegs = 0;
  19053. +
  19054. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  19055. + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
  19056. + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
  19057. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  19058. + re->re_src_io = (struct uio *)crp->crp_buf;
  19059. + re->re_dst_io = (struct uio *)crp->crp_buf;
  19060. + } else {
  19061. + safestats.st_badflags++;
  19062. + err = EINVAL;
  19063. + goto errout; /* XXX we don't handle contiguous blocks! */
  19064. + }
  19065. +
  19066. + sa = &re->re_sa;
  19067. + ses = &sc->sc_sessions[re->re_sesn];
  19068. +
  19069. + crd1 = crp->crp_desc;
  19070. + if (crd1 == NULL) {
  19071. + safestats.st_nodesc++;
  19072. + err = EINVAL;
  19073. + goto errout;
  19074. + }
  19075. + crd2 = crd1->crd_next;
  19076. +
  19077. + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
  19078. + cmd1 = 0;
  19079. + if (crd2 == NULL) {
  19080. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  19081. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  19082. + crd1->crd_alg == CRYPTO_NULL_HMAC) {
  19083. + maccrd = crd1;
  19084. + enccrd = NULL;
  19085. + cmd0 |= SAFE_SA_CMD0_OP_HASH;
  19086. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  19087. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  19088. + crd1->crd_alg == CRYPTO_AES_CBC ||
  19089. + crd1->crd_alg == CRYPTO_NULL_CBC) {
  19090. + maccrd = NULL;
  19091. + enccrd = crd1;
  19092. + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
  19093. + } else {
  19094. + safestats.st_badalg++;
  19095. + err = EINVAL;
  19096. + goto errout;
  19097. + }
  19098. + } else {
  19099. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  19100. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  19101. + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
  19102. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  19103. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  19104. + crd2->crd_alg == CRYPTO_AES_CBC ||
  19105. + crd2->crd_alg == CRYPTO_NULL_CBC) &&
  19106. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  19107. + maccrd = crd1;
  19108. + enccrd = crd2;
  19109. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  19110. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  19111. + crd1->crd_alg == CRYPTO_AES_CBC ||
  19112. + crd1->crd_alg == CRYPTO_NULL_CBC) &&
  19113. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  19114. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  19115. + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
  19116. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  19117. + enccrd = crd1;
  19118. + maccrd = crd2;
  19119. + } else {
  19120. + safestats.st_badalg++;
  19121. + err = EINVAL;
  19122. + goto errout;
  19123. + }
  19124. + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
  19125. + }
  19126. +
  19127. + if (enccrd) {
  19128. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  19129. + safe_setup_enckey(ses, enccrd->crd_key);
  19130. +
  19131. + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
  19132. + cmd0 |= SAFE_SA_CMD0_DES;
  19133. + cmd1 |= SAFE_SA_CMD1_CBC;
  19134. + ivsize = 2*sizeof(u_int32_t);
  19135. + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
  19136. + cmd0 |= SAFE_SA_CMD0_3DES;
  19137. + cmd1 |= SAFE_SA_CMD1_CBC;
  19138. + ivsize = 2*sizeof(u_int32_t);
  19139. + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
  19140. + cmd0 |= SAFE_SA_CMD0_AES;
  19141. + cmd1 |= SAFE_SA_CMD1_CBC;
  19142. + if (ses->ses_klen == 128)
  19143. + cmd1 |= SAFE_SA_CMD1_AES128;
  19144. + else if (ses->ses_klen == 192)
  19145. + cmd1 |= SAFE_SA_CMD1_AES192;
  19146. + else
  19147. + cmd1 |= SAFE_SA_CMD1_AES256;
  19148. + ivsize = 4*sizeof(u_int32_t);
  19149. + } else {
  19150. + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
  19151. + ivsize = 0;
  19152. + }
  19153. +
  19154. + /*
  19155. + * Setup encrypt/decrypt state. When using basic ops
  19156. + * we can't use an inline IV because hash/crypt offset
  19157. + * must be from the end of the IV to the start of the
  19158. + * crypt data and this leaves out the preceding header
  19159. + * from the hash calculation. Instead we place the IV
  19160. + * in the state record and set the hash/crypt offset to
  19161. + * copy both the header+IV.
  19162. + */
  19163. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  19164. + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
  19165. +
  19166. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  19167. + iv = enccrd->crd_iv;
  19168. + else
  19169. + iv = (caddr_t) ses->ses_iv;
  19170. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  19171. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  19172. + enccrd->crd_inject, ivsize, iv);
  19173. + }
  19174. + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
  19175. + /* make iv LE */
  19176. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  19177. + re->re_sastate.sa_saved_iv[i] =
  19178. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  19179. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
  19180. + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
  19181. + } else {
  19182. + cmd0 |= SAFE_SA_CMD0_INBOUND;
  19183. +
  19184. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  19185. + bcopy(enccrd->crd_iv,
  19186. + re->re_sastate.sa_saved_iv, ivsize);
  19187. + } else {
  19188. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  19189. + enccrd->crd_inject, ivsize,
  19190. + (caddr_t)re->re_sastate.sa_saved_iv);
  19191. + }
  19192. + /* make iv LE */
  19193. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  19194. + re->re_sastate.sa_saved_iv[i] =
  19195. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  19196. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
  19197. + }
  19198. + /*
  19199. + * For basic encryption use the zero pad algorithm.
  19200. + * This pads results to an 8-byte boundary and
  19201. + * suppresses padding verification for inbound (i.e.
  19202. + * decrypt) operations.
  19203. + *
  19204. + * NB: Not sure if the 8-byte pad boundary is a problem.
  19205. + */
  19206. + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
  19207. +
  19208. + /* XXX assert key bufs have the same size */
  19209. + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
  19210. + }
  19211. +
  19212. + if (maccrd) {
  19213. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  19214. + safe_setup_mackey(ses, maccrd->crd_alg,
  19215. + maccrd->crd_key, maccrd->crd_klen / 8);
  19216. + }
  19217. +
  19218. + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  19219. + cmd0 |= SAFE_SA_CMD0_MD5;
  19220. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  19221. + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
  19222. + cmd0 |= SAFE_SA_CMD0_SHA1;
  19223. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  19224. + } else {
  19225. + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
  19226. + }
  19227. + /*
  19228. + * Digest data is loaded from the SA and the hash
  19229. + * result is saved to the state block where we
  19230. + * retrieve it for return to the caller.
  19231. + */
  19232. + /* XXX assert digest bufs have the same size */
  19233. + bcopy(ses->ses_hminner, sa->sa_indigest,
  19234. + sizeof(sa->sa_indigest));
  19235. + bcopy(ses->ses_hmouter, sa->sa_outdigest,
  19236. + sizeof(sa->sa_outdigest));
  19237. +
  19238. + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
  19239. + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
  19240. + }
  19241. +
  19242. + if (enccrd && maccrd) {
  19243. + /*
  19244. + * The offset from hash data to the start of
  19245. + * crypt data is the difference in the skips.
  19246. + */
  19247. + bypass = maccrd->crd_skip;
  19248. + coffset = enccrd->crd_skip - maccrd->crd_skip;
  19249. + if (coffset < 0) {
  19250. + DPRINTF(("%s: hash does not precede crypt; "
  19251. + "mac skip %u enc skip %u\n",
  19252. + __func__, maccrd->crd_skip, enccrd->crd_skip));
  19253. + safestats.st_skipmismatch++;
  19254. + err = EINVAL;
  19255. + goto errout;
  19256. + }
  19257. + oplen = enccrd->crd_skip + enccrd->crd_len;
  19258. + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
  19259. + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
  19260. + __func__, maccrd->crd_skip + maccrd->crd_len,
  19261. + oplen));
  19262. + safestats.st_lenmismatch++;
  19263. + err = EINVAL;
  19264. + goto errout;
  19265. + }
  19266. +#ifdef SAFE_DEBUG
  19267. + if (debug) {
  19268. + printf("mac: skip %d, len %d, inject %d\n",
  19269. + maccrd->crd_skip, maccrd->crd_len,
  19270. + maccrd->crd_inject);
  19271. + printf("enc: skip %d, len %d, inject %d\n",
  19272. + enccrd->crd_skip, enccrd->crd_len,
  19273. + enccrd->crd_inject);
  19274. + printf("bypass %d coffset %d oplen %d\n",
  19275. + bypass, coffset, oplen);
  19276. + }
  19277. +#endif
  19278. + if (coffset & 3) { /* offset must be 32-bit aligned */
  19279. + DPRINTF(("%s: coffset %u misaligned\n",
  19280. + __func__, coffset));
  19281. + safestats.st_coffmisaligned++;
  19282. + err = EINVAL;
  19283. + goto errout;
  19284. + }
  19285. + coffset >>= 2;
  19286. + if (coffset > 255) { /* offset must be <256 dwords */
  19287. + DPRINTF(("%s: coffset %u too big\n",
  19288. + __func__, coffset));
  19289. + safestats.st_cofftoobig++;
  19290. + err = EINVAL;
  19291. + goto errout;
  19292. + }
  19293. + /*
  19294. + * Tell the hardware to copy the header to the output.
  19295. + * The header is defined as the data from the end of
  19296. + * the bypass to the start of data to be encrypted.
  19297. + * Typically this is the inline IV. Note that you need
  19298. + * to do this even if src+dst are the same; it appears
  19299. + * that w/o this bit the crypted data is written
  19300. + * immediately after the bypass data.
  19301. + */
  19302. + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
  19303. + /*
  19304. + * Disable IP header mutable bit handling. This is
  19305. + * needed to get correct HMAC calculations.
  19306. + */
  19307. + cmd1 |= SAFE_SA_CMD1_MUTABLE;
  19308. + } else {
  19309. + if (enccrd) {
  19310. + bypass = enccrd->crd_skip;
  19311. + oplen = bypass + enccrd->crd_len;
  19312. + } else {
  19313. + bypass = maccrd->crd_skip;
  19314. + oplen = bypass + maccrd->crd_len;
  19315. + }
  19316. + coffset = 0;
  19317. + }
  19318. + /* XXX verify multiple of 4 when using s/g */
  19319. + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
  19320. + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
  19321. + safestats.st_bypasstoobig++;
  19322. + err = EINVAL;
  19323. + goto errout;
  19324. + }
  19325. +
  19326. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  19327. + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
  19328. + safestats.st_noload++;
  19329. + err = ENOMEM;
  19330. + goto errout;
  19331. + }
  19332. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  19333. + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
  19334. + safestats.st_noload++;
  19335. + err = ENOMEM;
  19336. + goto errout;
  19337. + }
  19338. + }
  19339. + nicealign = safe_dmamap_aligned(sc, &re->re_src);
  19340. + uniform = safe_dmamap_uniform(sc, &re->re_src);
  19341. +
  19342. + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
  19343. + nicealign, uniform, re->re_src.nsegs));
  19344. + if (re->re_src.nsegs > 1) {
  19345. + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
  19346. + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
  19347. + for (i = 0; i < re->re_src_nsegs; i++) {
  19348. + /* NB: no need to check if there's space */
  19349. + pd = sc->sc_spfree;
  19350. + if (++(sc->sc_spfree) == sc->sc_springtop)
  19351. + sc->sc_spfree = sc->sc_spring;
  19352. +
  19353. + KASSERT((pd->pd_flags&3) == 0 ||
  19354. + (pd->pd_flags&3) == SAFE_PD_DONE,
  19355. + ("bogus source particle descriptor; flags %x",
  19356. + pd->pd_flags));
  19357. + pd->pd_addr = re->re_src_segs[i].ds_addr;
  19358. + pd->pd_size = re->re_src_segs[i].ds_len;
  19359. + pd->pd_flags = SAFE_PD_READY;
  19360. + }
  19361. + cmd0 |= SAFE_SA_CMD0_IGATHER;
  19362. + } else {
  19363. + /*
  19364. + * No need for gather, reference the operand directly.
  19365. + */
  19366. + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
  19367. + }
  19368. +
  19369. + if (enccrd == NULL && maccrd != NULL) {
  19370. + /*
  19371. + * Hash op; no destination needed.
  19372. + */
  19373. + } else {
  19374. + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
  19375. + if (!nicealign) {
  19376. + safestats.st_iovmisaligned++;
  19377. + err = EINVAL;
  19378. + goto errout;
  19379. + }
  19380. + if (uniform != 1) {
  19381. + device_printf(sc->sc_dev, "!uniform source\n");
  19382. + if (!uniform) {
  19383. + /*
  19384. + * There's no way to handle the DMA
  19385. + * requirements with this uio. We
  19386. + * could create a separate DMA area for
  19387. + * the result and then copy it back,
  19388. + * but for now we just bail and return
  19389. + * an error. Note that uio requests
  19390. + * > SAFE_MAX_DSIZE are handled because
  19391. + * the DMA map and segment list for the
  19392. + * destination wil result in a
  19393. + * destination particle list that does
  19394. + * the necessary scatter DMA.
  19395. + */
  19396. + safestats.st_iovnotuniform++;
  19397. + err = EINVAL;
  19398. + goto errout;
  19399. + }
  19400. + } else
  19401. + re->re_dst = re->re_src;
  19402. + } else {
  19403. + safestats.st_badflags++;
  19404. + err = EINVAL;
  19405. + goto errout;
  19406. + }
  19407. +
  19408. + if (re->re_dst.nsegs > 1) {
  19409. + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
  19410. + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
  19411. + for (i = 0; i < re->re_dst_nsegs; i++) {
  19412. + pd = sc->sc_dpfree;
  19413. + KASSERT((pd->pd_flags&3) == 0 ||
  19414. + (pd->pd_flags&3) == SAFE_PD_DONE,
  19415. + ("bogus dest particle descriptor; flags %x",
  19416. + pd->pd_flags));
  19417. + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
  19418. + sc->sc_dpfree = sc->sc_dpring;
  19419. + pd->pd_addr = re->re_dst_segs[i].ds_addr;
  19420. + pd->pd_flags = SAFE_PD_READY;
  19421. + }
  19422. + cmd0 |= SAFE_SA_CMD0_OSCATTER;
  19423. + } else {
  19424. + /*
  19425. + * No need for scatter, reference the operand directly.
  19426. + */
  19427. + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
  19428. + }
  19429. + }
  19430. +
  19431. + /*
  19432. + * All done with setup; fillin the SA command words
  19433. + * and the packet engine descriptor. The operation
  19434. + * is now ready for submission to the hardware.
  19435. + */
  19436. + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
  19437. + sa->sa_cmd1 = cmd1
  19438. + | (coffset << SAFE_SA_CMD1_OFFSET_S)
  19439. + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
  19440. + | SAFE_SA_CMD1_SRPCI
  19441. + ;
  19442. + /*
  19443. + * NB: the order of writes is important here. In case the
  19444. + * chip is scanning the ring because of an outstanding request
  19445. + * it might nab this one too. In that case we need to make
  19446. + * sure the setup is complete before we write the length
  19447. + * field of the descriptor as it signals the descriptor is
  19448. + * ready for processing.
  19449. + */
  19450. + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
  19451. + if (maccrd)
  19452. + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
  19453. + wmb();
  19454. + re->re_desc.d_len = oplen
  19455. + | SAFE_PE_LEN_READY
  19456. + | (bypass << SAFE_PE_LEN_BYPASS_S)
  19457. + ;
  19458. +
  19459. + safestats.st_ipackets++;
  19460. + safestats.st_ibytes += oplen;
  19461. +
  19462. + if (++(sc->sc_front) == sc->sc_ringtop)
  19463. + sc->sc_front = sc->sc_ring;
  19464. +
  19465. + /* XXX honor batching */
  19466. + safe_feed(sc, re);
  19467. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  19468. + return (0);
  19469. +
  19470. +errout:
  19471. + if (re->re_src.map != re->re_dst.map)
  19472. + pci_unmap_operand(sc, &re->re_dst);
  19473. + if (re->re_src.map)
  19474. + pci_unmap_operand(sc, &re->re_src);
  19475. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  19476. + if (err != ERESTART) {
  19477. + crp->crp_etype = err;
  19478. + crypto_done(crp);
  19479. + } else {
  19480. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  19481. + }
  19482. + return (err);
  19483. +}
  19484. +
  19485. +static void
  19486. +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
  19487. +{
  19488. + struct cryptop *crp = (struct cryptop *)re->re_crp;
  19489. + struct cryptodesc *crd;
  19490. +
  19491. + DPRINTF(("%s()\n", __FUNCTION__));
  19492. +
  19493. + safestats.st_opackets++;
  19494. + safestats.st_obytes += re->re_dst.mapsize;
  19495. +
  19496. + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
  19497. + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
  19498. + re->re_desc.d_csr,
  19499. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
  19500. + safestats.st_peoperr++;
  19501. + crp->crp_etype = EIO; /* something more meaningful? */
  19502. + }
  19503. +
  19504. + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
  19505. + pci_unmap_operand(sc, &re->re_dst);
  19506. + pci_unmap_operand(sc, &re->re_src);
  19507. +
  19508. + /*
  19509. + * If result was written to a differet mbuf chain, swap
  19510. + * it in as the return value and reclaim the original.
  19511. + */
  19512. + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
  19513. + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
  19514. + /* kfree_skb(skb) */
  19515. + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
  19516. + return;
  19517. + }
  19518. +
  19519. + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
  19520. + /* copy out IV for future use */
  19521. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  19522. + int i;
  19523. + int ivsize;
  19524. +
  19525. + if (crd->crd_alg == CRYPTO_DES_CBC ||
  19526. + crd->crd_alg == CRYPTO_3DES_CBC) {
  19527. + ivsize = 2*sizeof(u_int32_t);
  19528. + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
  19529. + ivsize = 4*sizeof(u_int32_t);
  19530. + } else
  19531. + continue;
  19532. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  19533. + crd->crd_skip + crd->crd_len - ivsize, ivsize,
  19534. + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
  19535. + for (i = 0;
  19536. + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
  19537. + i++)
  19538. + sc->sc_sessions[re->re_sesn].ses_iv[i] =
  19539. + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
  19540. + break;
  19541. + }
  19542. + }
  19543. +
  19544. + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
  19545. + /* copy out ICV result */
  19546. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  19547. + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
  19548. + crd->crd_alg == CRYPTO_SHA1_HMAC ||
  19549. + crd->crd_alg == CRYPTO_NULL_HMAC))
  19550. + continue;
  19551. + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
  19552. + /*
  19553. + * SHA-1 ICV's are byte-swapped; fix 'em up
  19554. + * before copy them to their destination.
  19555. + */
  19556. + re->re_sastate.sa_saved_indigest[0] =
  19557. + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
  19558. + re->re_sastate.sa_saved_indigest[1] =
  19559. + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
  19560. + re->re_sastate.sa_saved_indigest[2] =
  19561. + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
  19562. + } else {
  19563. + re->re_sastate.sa_saved_indigest[0] =
  19564. + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
  19565. + re->re_sastate.sa_saved_indigest[1] =
  19566. + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
  19567. + re->re_sastate.sa_saved_indigest[2] =
  19568. + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
  19569. + }
  19570. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  19571. + crd->crd_inject,
  19572. + sc->sc_sessions[re->re_sesn].ses_mlen,
  19573. + (caddr_t)re->re_sastate.sa_saved_indigest);
  19574. + break;
  19575. + }
  19576. + }
  19577. + crypto_done(crp);
  19578. +}
  19579. +
  19580. +
  19581. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  19582. +#define SAFE_RNG_MAXWAIT 1000
  19583. +
  19584. +static void
  19585. +safe_rng_init(struct safe_softc *sc)
  19586. +{
  19587. + u_int32_t w, v;
  19588. + int i;
  19589. +
  19590. + DPRINTF(("%s()\n", __FUNCTION__));
  19591. +
  19592. + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
  19593. + /* use default value according to the manual */
  19594. + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
  19595. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  19596. +
  19597. + /*
  19598. + * There is a bug in rev 1.0 of the 1140 that when the RNG
  19599. + * is brought out of reset the ready status flag does not
  19600. + * work until the RNG has finished its internal initialization.
  19601. + *
  19602. + * So in order to determine the device is through its
  19603. + * initialization we must read the data register, using the
  19604. + * status reg in the read in case it is initialized. Then read
  19605. + * the data register until it changes from the first read.
  19606. + * Once it changes read the data register until it changes
  19607. + * again. At this time the RNG is considered initialized.
  19608. + * This could take between 750ms - 1000ms in time.
  19609. + */
  19610. + i = 0;
  19611. + w = READ_REG(sc, SAFE_RNG_OUT);
  19612. + do {
  19613. + v = READ_REG(sc, SAFE_RNG_OUT);
  19614. + if (v != w) {
  19615. + w = v;
  19616. + break;
  19617. + }
  19618. + DELAY(10);
  19619. + } while (++i < SAFE_RNG_MAXWAIT);
  19620. +
  19621. + /* Wait Until data changes again */
  19622. + i = 0;
  19623. + do {
  19624. + v = READ_REG(sc, SAFE_RNG_OUT);
  19625. + if (v != w)
  19626. + break;
  19627. + DELAY(10);
  19628. + } while (++i < SAFE_RNG_MAXWAIT);
  19629. +}
  19630. +
  19631. +static __inline void
  19632. +safe_rng_disable_short_cycle(struct safe_softc *sc)
  19633. +{
  19634. + DPRINTF(("%s()\n", __FUNCTION__));
  19635. +
  19636. + WRITE_REG(sc, SAFE_RNG_CTRL,
  19637. + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
  19638. +}
  19639. +
  19640. +static __inline void
  19641. +safe_rng_enable_short_cycle(struct safe_softc *sc)
  19642. +{
  19643. + DPRINTF(("%s()\n", __FUNCTION__));
  19644. +
  19645. + WRITE_REG(sc, SAFE_RNG_CTRL,
  19646. + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
  19647. +}
  19648. +
  19649. +static __inline u_int32_t
  19650. +safe_rng_read(struct safe_softc *sc)
  19651. +{
  19652. + int i;
  19653. +
  19654. + i = 0;
  19655. + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
  19656. + ;
  19657. + return READ_REG(sc, SAFE_RNG_OUT);
  19658. +}
  19659. +
  19660. +static int
  19661. +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
  19662. +{
  19663. + struct safe_softc *sc = (struct safe_softc *) arg;
  19664. + int i, rc;
  19665. +
  19666. + DPRINTF(("%s()\n", __FUNCTION__));
  19667. +
  19668. + safestats.st_rng++;
  19669. + /*
  19670. + * Fetch the next block of data.
  19671. + */
  19672. + if (maxwords > safe_rngbufsize)
  19673. + maxwords = safe_rngbufsize;
  19674. + if (maxwords > SAFE_RNG_MAXBUFSIZ)
  19675. + maxwords = SAFE_RNG_MAXBUFSIZ;
  19676. +retry:
  19677. + /* read as much as we can */
  19678. + for (rc = 0; rc < maxwords; rc++) {
  19679. + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
  19680. + break;
  19681. + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
  19682. + }
  19683. + if (rc == 0)
  19684. + return 0;
  19685. + /*
  19686. + * Check the comparator alarm count and reset the h/w if
  19687. + * it exceeds our threshold. This guards against the
  19688. + * hardware oscillators resonating with external signals.
  19689. + */
  19690. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
  19691. + u_int32_t freq_inc, w;
  19692. +
  19693. + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
  19694. + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
  19695. + safestats.st_rngalarm++;
  19696. + safe_rng_enable_short_cycle(sc);
  19697. + freq_inc = 18;
  19698. + for (i = 0; i < 64; i++) {
  19699. + w = READ_REG(sc, SAFE_RNG_CNFG);
  19700. + freq_inc = ((w + freq_inc) & 0x3fL);
  19701. + w = ((w & ~0x3fL) | freq_inc);
  19702. + WRITE_REG(sc, SAFE_RNG_CNFG, w);
  19703. +
  19704. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  19705. +
  19706. + (void) safe_rng_read(sc);
  19707. + DELAY(25);
  19708. +
  19709. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
  19710. + safe_rng_disable_short_cycle(sc);
  19711. + goto retry;
  19712. + }
  19713. + freq_inc = 1;
  19714. + }
  19715. + safe_rng_disable_short_cycle(sc);
  19716. + } else
  19717. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  19718. +
  19719. + return(rc);
  19720. +}
  19721. +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
  19722. +
  19723. +
  19724. +/*
  19725. + * Resets the board. Values in the regesters are left as is
  19726. + * from the reset (i.e. initial values are assigned elsewhere).
  19727. + */
  19728. +static void
  19729. +safe_reset_board(struct safe_softc *sc)
  19730. +{
  19731. + u_int32_t v;
  19732. + /*
  19733. + * Reset the device. The manual says no delay
  19734. + * is needed between marking and clearing reset.
  19735. + */
  19736. + DPRINTF(("%s()\n", __FUNCTION__));
  19737. +
  19738. + v = READ_REG(sc, SAFE_PE_DMACFG) &~
  19739. + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
  19740. + SAFE_PE_DMACFG_SGRESET);
  19741. + WRITE_REG(sc, SAFE_PE_DMACFG, v
  19742. + | SAFE_PE_DMACFG_PERESET
  19743. + | SAFE_PE_DMACFG_PDRRESET
  19744. + | SAFE_PE_DMACFG_SGRESET);
  19745. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  19746. +}
  19747. +
  19748. +/*
  19749. + * Initialize registers we need to touch only once.
  19750. + */
  19751. +static void
  19752. +safe_init_board(struct safe_softc *sc)
  19753. +{
  19754. + u_int32_t v, dwords;
  19755. +
  19756. + DPRINTF(("%s()\n", __FUNCTION__));
  19757. +
  19758. + v = READ_REG(sc, SAFE_PE_DMACFG);
  19759. + v &=~ ( SAFE_PE_DMACFG_PEMODE
  19760. + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
  19761. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  19762. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  19763. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  19764. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  19765. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  19766. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  19767. + );
  19768. + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
  19769. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  19770. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  19771. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  19772. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  19773. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  19774. +#if 0
  19775. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  19776. +#endif
  19777. + ;
  19778. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  19779. +
  19780. +#ifdef __BIG_ENDIAN
  19781. + /* tell the safenet that we are 4321 and not 1234 */
  19782. + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
  19783. +#endif
  19784. +
  19785. + if (sc->sc_chiprev == SAFE_REV(1,0)) {
  19786. + /*
  19787. + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
  19788. + * "target mode transfers" done while the chip is DMA'ing
  19789. + * >1020 bytes cause the hardware to lockup. To avoid this
  19790. + * we reduce the max PCI transfer size and use small source
  19791. + * particle descriptors (<= 256 bytes).
  19792. + */
  19793. + WRITE_REG(sc, SAFE_DMA_CFG, 256);
  19794. + device_printf(sc->sc_dev,
  19795. + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
  19796. + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
  19797. + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
  19798. + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
  19799. + sc->sc_max_dsize = 256;
  19800. + } else {
  19801. + sc->sc_max_dsize = SAFE_MAX_DSIZE;
  19802. + }
  19803. +
  19804. + /* NB: operands+results are overlaid */
  19805. + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
  19806. + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
  19807. + /*
  19808. + * Configure ring entry size and number of items in the ring.
  19809. + */
  19810. + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
  19811. + ("PE ring entry not 32-bit aligned!"));
  19812. + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
  19813. + WRITE_REG(sc, SAFE_PE_RINGCFG,
  19814. + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
  19815. + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
  19816. +
  19817. + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
  19818. + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
  19819. + WRITE_REG(sc, SAFE_PE_PARTSIZE,
  19820. + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
  19821. + /*
  19822. + * NB: destination particles are fixed size. We use
  19823. + * an mbuf cluster and require all results go to
  19824. + * clusters or smaller.
  19825. + */
  19826. + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
  19827. +
  19828. + /* it's now safe to enable PE mode, do it */
  19829. + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
  19830. +
  19831. + /*
  19832. + * Configure hardware to use level-triggered interrupts and
  19833. + * to interrupt after each descriptor is processed.
  19834. + */
  19835. + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
  19836. + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
  19837. + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
  19838. + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
  19839. +}
  19840. +
  19841. +
  19842. +/*
  19843. + * Clean up after a chip crash.
  19844. + * It is assumed that the caller in splimp()
  19845. + */
  19846. +static void
  19847. +safe_cleanchip(struct safe_softc *sc)
  19848. +{
  19849. + DPRINTF(("%s()\n", __FUNCTION__));
  19850. +
  19851. + if (sc->sc_nqchip != 0) {
  19852. + struct safe_ringentry *re = sc->sc_back;
  19853. +
  19854. + while (re != sc->sc_front) {
  19855. + if (re->re_desc.d_csr != 0)
  19856. + safe_free_entry(sc, re);
  19857. + if (++re == sc->sc_ringtop)
  19858. + re = sc->sc_ring;
  19859. + }
  19860. + sc->sc_back = re;
  19861. + sc->sc_nqchip = 0;
  19862. + }
  19863. +}
  19864. +
  19865. +/*
  19866. + * free a safe_q
  19867. + * It is assumed that the caller is within splimp().
  19868. + */
  19869. +static int
  19870. +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
  19871. +{
  19872. + struct cryptop *crp;
  19873. +
  19874. + DPRINTF(("%s()\n", __FUNCTION__));
  19875. +
  19876. + /*
  19877. + * Free header MCR
  19878. + */
  19879. + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
  19880. +#ifdef NOTYET
  19881. + m_freem(re->re_dst_m);
  19882. +#else
  19883. + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
  19884. +#endif
  19885. +
  19886. + crp = (struct cryptop *)re->re_crp;
  19887. +
  19888. + re->re_desc.d_csr = 0;
  19889. +
  19890. + crp->crp_etype = EFAULT;
  19891. + crypto_done(crp);
  19892. + return(0);
  19893. +}
  19894. +
  19895. +/*
  19896. + * Routine to reset the chip and clean up.
  19897. + * It is assumed that the caller is in splimp()
  19898. + */
  19899. +static void
  19900. +safe_totalreset(struct safe_softc *sc)
  19901. +{
  19902. + DPRINTF(("%s()\n", __FUNCTION__));
  19903. +
  19904. + safe_reset_board(sc);
  19905. + safe_init_board(sc);
  19906. + safe_cleanchip(sc);
  19907. +}
  19908. +
  19909. +/*
  19910. + * Is the operand suitable aligned for direct DMA. Each
  19911. + * segment must be aligned on a 32-bit boundary and all
  19912. + * but the last segment must be a multiple of 4 bytes.
  19913. + */
  19914. +static int
  19915. +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
  19916. +{
  19917. + int i;
  19918. +
  19919. + DPRINTF(("%s()\n", __FUNCTION__));
  19920. +
  19921. + for (i = 0; i < op->nsegs; i++) {
  19922. + if (op->segs[i].ds_addr & 3)
  19923. + return (0);
  19924. + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
  19925. + return (0);
  19926. + }
  19927. + return (1);
  19928. +}
  19929. +
  19930. +/*
  19931. + * Is the operand suitable for direct DMA as the destination
  19932. + * of an operation. The hardware requires that each ``particle''
  19933. + * but the last in an operation result have the same size. We
  19934. + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
  19935. + * 0 if some segment is not a multiple of of this size, 1 if all
  19936. + * segments are exactly this size, or 2 if segments are at worst
  19937. + * a multple of this size.
  19938. + */
  19939. +static int
  19940. +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
  19941. +{
  19942. + int result = 1;
  19943. +
  19944. + DPRINTF(("%s()\n", __FUNCTION__));
  19945. +
  19946. + if (op->nsegs > 0) {
  19947. + int i;
  19948. +
  19949. + for (i = 0; i < op->nsegs-1; i++) {
  19950. + if (op->segs[i].ds_len % sc->sc_max_dsize)
  19951. + return (0);
  19952. + if (op->segs[i].ds_len != sc->sc_max_dsize)
  19953. + result = 2;
  19954. + }
  19955. + }
  19956. + return (result);
  19957. +}
  19958. +
  19959. +static int
  19960. +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
  19961. +{
  19962. + struct safe_softc *sc = device_get_softc(dev);
  19963. + struct safe_pkq *q;
  19964. + unsigned long flags;
  19965. +
  19966. + DPRINTF(("%s()\n", __FUNCTION__));
  19967. +
  19968. + if (sc == NULL) {
  19969. + krp->krp_status = EINVAL;
  19970. + goto err;
  19971. + }
  19972. +
  19973. + if (krp->krp_op != CRK_MOD_EXP) {
  19974. + krp->krp_status = EOPNOTSUPP;
  19975. + goto err;
  19976. + }
  19977. +
  19978. + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  19979. + if (q == NULL) {
  19980. + krp->krp_status = ENOMEM;
  19981. + goto err;
  19982. + }
  19983. + memset(q, 0, sizeof(*q));
  19984. + q->pkq_krp = krp;
  19985. + INIT_LIST_HEAD(&q->pkq_list);
  19986. +
  19987. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  19988. + list_add_tail(&q->pkq_list, &sc->sc_pkq);
  19989. + safe_kfeed(sc);
  19990. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  19991. + return (0);
  19992. +
  19993. +err:
  19994. + crypto_kdone(krp);
  19995. + return (0);
  19996. +}
  19997. +
  19998. +#define SAFE_CRK_PARAM_BASE 0
  19999. +#define SAFE_CRK_PARAM_EXP 1
  20000. +#define SAFE_CRK_PARAM_MOD 2
  20001. +
  20002. +static int
  20003. +safe_kstart(struct safe_softc *sc)
  20004. +{
  20005. + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
  20006. + int exp_bits, mod_bits, base_bits;
  20007. + u_int32_t op, a_off, b_off, c_off, d_off;
  20008. +
  20009. + DPRINTF(("%s()\n", __FUNCTION__));
  20010. +
  20011. + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
  20012. + krp->krp_status = EINVAL;
  20013. + return (1);
  20014. + }
  20015. +
  20016. + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  20017. + if (base_bits > 2048)
  20018. + goto too_big;
  20019. + if (base_bits <= 0) /* 5. base not zero */
  20020. + goto too_small;
  20021. +
  20022. + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  20023. + if (exp_bits > 2048)
  20024. + goto too_big;
  20025. + if (exp_bits <= 0) /* 1. exponent word length > 0 */
  20026. + goto too_small; /* 4. exponent not zero */
  20027. +
  20028. + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  20029. + if (mod_bits > 2048)
  20030. + goto too_big;
  20031. + if (mod_bits <= 32) /* 2. modulus word length > 1 */
  20032. + goto too_small; /* 8. MSW of modulus != zero */
  20033. + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
  20034. + goto too_small;
  20035. + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
  20036. + goto bad_domain; /* 6. modulus is odd */
  20037. + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
  20038. + goto too_small; /* make sure result will fit */
  20039. +
  20040. + /* 7. modulus > base */
  20041. + if (mod_bits < base_bits)
  20042. + goto too_small;
  20043. + if (mod_bits == base_bits) {
  20044. + u_int8_t *basep, *modp;
  20045. + int i;
  20046. +
  20047. + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
  20048. + ((base_bits + 7) / 8) - 1;
  20049. + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
  20050. + ((mod_bits + 7) / 8) - 1;
  20051. +
  20052. + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
  20053. + if (*modp < *basep)
  20054. + goto too_small;
  20055. + if (*modp > *basep)
  20056. + break;
  20057. + }
  20058. + }
  20059. +
  20060. + /* And on the 9th step, he rested. */
  20061. +
  20062. + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
  20063. + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
  20064. + if (mod_bits > 1024) {
  20065. + op = SAFE_PK_FUNC_EXP4;
  20066. + a_off = 0x000;
  20067. + b_off = 0x100;
  20068. + c_off = 0x200;
  20069. + d_off = 0x300;
  20070. + } else {
  20071. + op = SAFE_PK_FUNC_EXP16;
  20072. + a_off = 0x000;
  20073. + b_off = 0x080;
  20074. + c_off = 0x100;
  20075. + d_off = 0x180;
  20076. + }
  20077. + sc->sc_pk_reslen = b_off - a_off;
  20078. + sc->sc_pk_resoff = d_off;
  20079. +
  20080. + /* A is exponent, B is modulus, C is base, D is result */
  20081. + safe_kload_reg(sc, a_off, b_off - a_off,
  20082. + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  20083. + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
  20084. + safe_kload_reg(sc, b_off, b_off - a_off,
  20085. + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  20086. + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
  20087. + safe_kload_reg(sc, c_off, b_off - a_off,
  20088. + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  20089. + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
  20090. + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
  20091. +
  20092. + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
  20093. +
  20094. + return (0);
  20095. +
  20096. +too_big:
  20097. + krp->krp_status = E2BIG;
  20098. + return (1);
  20099. +too_small:
  20100. + krp->krp_status = ERANGE;
  20101. + return (1);
  20102. +bad_domain:
  20103. + krp->krp_status = EDOM;
  20104. + return (1);
  20105. +}
  20106. +
  20107. +static int
  20108. +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
  20109. +{
  20110. + u_int plen = (cr->crp_nbits + 7) / 8;
  20111. + int i, sig = plen * 8;
  20112. + u_int8_t c, *p = cr->crp_p;
  20113. +
  20114. + DPRINTF(("%s()\n", __FUNCTION__));
  20115. +
  20116. + for (i = plen - 1; i >= 0; i--) {
  20117. + c = p[i];
  20118. + if (c != 0) {
  20119. + while ((c & 0x80) == 0) {
  20120. + sig--;
  20121. + c <<= 1;
  20122. + }
  20123. + break;
  20124. + }
  20125. + sig -= 8;
  20126. + }
  20127. + return (sig);
  20128. +}
  20129. +
  20130. +static void
  20131. +safe_kfeed(struct safe_softc *sc)
  20132. +{
  20133. + struct safe_pkq *q, *tmp;
  20134. +
  20135. + DPRINTF(("%s()\n", __FUNCTION__));
  20136. +
  20137. + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
  20138. + return;
  20139. + if (sc->sc_pkq_cur != NULL)
  20140. + return;
  20141. + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
  20142. + sc->sc_pkq_cur = q;
  20143. + list_del(&q->pkq_list);
  20144. + if (safe_kstart(sc) != 0) {
  20145. + crypto_kdone(q->pkq_krp);
  20146. + kfree(q);
  20147. + sc->sc_pkq_cur = NULL;
  20148. + } else {
  20149. + /* op started, start polling */
  20150. + mod_timer(&sc->sc_pkto, jiffies + 1);
  20151. + break;
  20152. + }
  20153. + }
  20154. +}
  20155. +
  20156. +static void
  20157. +safe_kpoll(unsigned long arg)
  20158. +{
  20159. + struct safe_softc *sc = NULL;
  20160. + struct safe_pkq *q;
  20161. + struct crparam *res;
  20162. + int i;
  20163. + u_int32_t buf[64];
  20164. + unsigned long flags;
  20165. +
  20166. + DPRINTF(("%s()\n", __FUNCTION__));
  20167. +
  20168. + if (arg >= SAFE_MAX_CHIPS)
  20169. + return;
  20170. + sc = safe_chip_idx[arg];
  20171. + if (!sc) {
  20172. + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
  20173. + return;
  20174. + }
  20175. +
  20176. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  20177. + if (sc->sc_pkq_cur == NULL)
  20178. + goto out;
  20179. + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
  20180. + /* still running, check back later */
  20181. + mod_timer(&sc->sc_pkto, jiffies + 1);
  20182. + goto out;
  20183. + }
  20184. +
  20185. + q = sc->sc_pkq_cur;
  20186. + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
  20187. + bzero(buf, sizeof(buf));
  20188. + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
  20189. + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
  20190. + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
  20191. + sc->sc_pk_resoff + (i << 2)));
  20192. + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
  20193. + /*
  20194. + * reduce the bits that need copying if possible
  20195. + */
  20196. + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
  20197. + res->crp_nbits = safe_ksigbits(sc, res);
  20198. +
  20199. + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
  20200. + WRITE_REG(sc, i, 0);
  20201. +
  20202. + crypto_kdone(q->pkq_krp);
  20203. + kfree(q);
  20204. + sc->sc_pkq_cur = NULL;
  20205. +
  20206. + safe_kfeed(sc);
  20207. +out:
  20208. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  20209. +}
  20210. +
  20211. +static void
  20212. +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
  20213. + struct crparam *n)
  20214. +{
  20215. + u_int32_t buf[64], i;
  20216. +
  20217. + DPRINTF(("%s()\n", __FUNCTION__));
  20218. +
  20219. + bzero(buf, sizeof(buf));
  20220. + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
  20221. +
  20222. + for (i = 0; i < len >> 2; i++)
  20223. + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
  20224. + cpu_to_le32(buf[i]));
  20225. +}
  20226. +
  20227. +#ifdef SAFE_DEBUG
  20228. +static void
  20229. +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
  20230. +{
  20231. + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
  20232. + , tag
  20233. + , READ_REG(sc, SAFE_DMA_ENDIAN)
  20234. + , READ_REG(sc, SAFE_DMA_SRCADDR)
  20235. + , READ_REG(sc, SAFE_DMA_DSTADDR)
  20236. + , READ_REG(sc, SAFE_DMA_STAT)
  20237. + );
  20238. +}
  20239. +
  20240. +static void
  20241. +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
  20242. +{
  20243. + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
  20244. + , tag
  20245. + , READ_REG(sc, SAFE_HI_CFG)
  20246. + , READ_REG(sc, SAFE_HI_MASK)
  20247. + , READ_REG(sc, SAFE_HI_DESC_CNT)
  20248. + , READ_REG(sc, SAFE_HU_STAT)
  20249. + , READ_REG(sc, SAFE_HM_STAT)
  20250. + );
  20251. +}
  20252. +
  20253. +static void
  20254. +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
  20255. +{
  20256. + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
  20257. +
  20258. + /* NB: assume caller has lock on ring */
  20259. + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
  20260. + tag,
  20261. + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
  20262. + (unsigned long)(sc->sc_back - sc->sc_ring),
  20263. + (unsigned long)(sc->sc_front - sc->sc_ring));
  20264. +}
  20265. +
  20266. +static void
  20267. +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
  20268. +{
  20269. + int ix, nsegs;
  20270. +
  20271. + ix = re - sc->sc_ring;
  20272. + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
  20273. + , tag
  20274. + , re, ix
  20275. + , re->re_desc.d_csr
  20276. + , re->re_desc.d_src
  20277. + , re->re_desc.d_dst
  20278. + , re->re_desc.d_sa
  20279. + , re->re_desc.d_len
  20280. + );
  20281. + if (re->re_src.nsegs > 1) {
  20282. + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
  20283. + sizeof(struct safe_pdesc);
  20284. + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
  20285. + printf(" spd[%u] %p: %p size %u flags %x"
  20286. + , ix, &sc->sc_spring[ix]
  20287. + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
  20288. + , sc->sc_spring[ix].pd_size
  20289. + , sc->sc_spring[ix].pd_flags
  20290. + );
  20291. + if (sc->sc_spring[ix].pd_size == 0)
  20292. + printf(" (zero!)");
  20293. + printf("\n");
  20294. + if (++ix == SAFE_TOTAL_SPART)
  20295. + ix = 0;
  20296. + }
  20297. + }
  20298. + if (re->re_dst.nsegs > 1) {
  20299. + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
  20300. + sizeof(struct safe_pdesc);
  20301. + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
  20302. + printf(" dpd[%u] %p: %p flags %x\n"
  20303. + , ix, &sc->sc_dpring[ix]
  20304. + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
  20305. + , sc->sc_dpring[ix].pd_flags
  20306. + );
  20307. + if (++ix == SAFE_TOTAL_DPART)
  20308. + ix = 0;
  20309. + }
  20310. + }
  20311. + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
  20312. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
  20313. + printf("sa: key %x %x %x %x %x %x %x %x\n"
  20314. + , re->re_sa.sa_key[0]
  20315. + , re->re_sa.sa_key[1]
  20316. + , re->re_sa.sa_key[2]
  20317. + , re->re_sa.sa_key[3]
  20318. + , re->re_sa.sa_key[4]
  20319. + , re->re_sa.sa_key[5]
  20320. + , re->re_sa.sa_key[6]
  20321. + , re->re_sa.sa_key[7]
  20322. + );
  20323. + printf("sa: indigest %x %x %x %x %x\n"
  20324. + , re->re_sa.sa_indigest[0]
  20325. + , re->re_sa.sa_indigest[1]
  20326. + , re->re_sa.sa_indigest[2]
  20327. + , re->re_sa.sa_indigest[3]
  20328. + , re->re_sa.sa_indigest[4]
  20329. + );
  20330. + printf("sa: outdigest %x %x %x %x %x\n"
  20331. + , re->re_sa.sa_outdigest[0]
  20332. + , re->re_sa.sa_outdigest[1]
  20333. + , re->re_sa.sa_outdigest[2]
  20334. + , re->re_sa.sa_outdigest[3]
  20335. + , re->re_sa.sa_outdigest[4]
  20336. + );
  20337. + printf("sr: iv %x %x %x %x\n"
  20338. + , re->re_sastate.sa_saved_iv[0]
  20339. + , re->re_sastate.sa_saved_iv[1]
  20340. + , re->re_sastate.sa_saved_iv[2]
  20341. + , re->re_sastate.sa_saved_iv[3]
  20342. + );
  20343. + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
  20344. + , re->re_sastate.sa_saved_hashbc
  20345. + , re->re_sastate.sa_saved_indigest[0]
  20346. + , re->re_sastate.sa_saved_indigest[1]
  20347. + , re->re_sastate.sa_saved_indigest[2]
  20348. + , re->re_sastate.sa_saved_indigest[3]
  20349. + , re->re_sastate.sa_saved_indigest[4]
  20350. + );
  20351. +}
  20352. +
  20353. +static void
  20354. +safe_dump_ring(struct safe_softc *sc, const char *tag)
  20355. +{
  20356. + unsigned long flags;
  20357. +
  20358. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  20359. + printf("\nSafeNet Ring State:\n");
  20360. + safe_dump_intrstate(sc, tag);
  20361. + safe_dump_dmastatus(sc, tag);
  20362. + safe_dump_ringstate(sc, tag);
  20363. + if (sc->sc_nqchip) {
  20364. + struct safe_ringentry *re = sc->sc_back;
  20365. + do {
  20366. + safe_dump_request(sc, tag, re);
  20367. + if (++re == sc->sc_ringtop)
  20368. + re = sc->sc_ring;
  20369. + } while (re != sc->sc_front);
  20370. + }
  20371. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  20372. +}
  20373. +#endif /* SAFE_DEBUG */
  20374. +
  20375. +
  20376. +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  20377. +{
  20378. + struct safe_softc *sc = NULL;
  20379. + u32 mem_start, mem_len, cmd;
  20380. + int i, rc, devinfo;
  20381. + dma_addr_t raddr;
  20382. + static int num_chips = 0;
  20383. +
  20384. + DPRINTF(("%s()\n", __FUNCTION__));
  20385. +
  20386. + if (pci_enable_device(dev) < 0)
  20387. + return(-ENODEV);
  20388. +
  20389. + if (!dev->irq) {
  20390. + printk("safe: found device with no IRQ assigned. check BIOS settings!");
  20391. + pci_disable_device(dev);
  20392. + return(-ENODEV);
  20393. + }
  20394. +
  20395. + if (pci_set_mwi(dev)) {
  20396. + printk("safe: pci_set_mwi failed!");
  20397. + return(-ENODEV);
  20398. + }
  20399. +
  20400. + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  20401. + if (!sc)
  20402. + return(-ENOMEM);
  20403. + memset(sc, 0, sizeof(*sc));
  20404. +
  20405. + softc_device_init(sc, "safe", num_chips, safe_methods);
  20406. +
  20407. + sc->sc_irq = -1;
  20408. + sc->sc_cid = -1;
  20409. + sc->sc_pcidev = dev;
  20410. + if (num_chips < SAFE_MAX_CHIPS) {
  20411. + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
  20412. + num_chips++;
  20413. + }
  20414. +
  20415. + INIT_LIST_HEAD(&sc->sc_pkq);
  20416. + spin_lock_init(&sc->sc_pkmtx);
  20417. +
  20418. + pci_set_drvdata(sc->sc_pcidev, sc);
  20419. +
  20420. + /* we read its hardware registers as memory */
  20421. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  20422. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  20423. +
  20424. + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
  20425. + if (!sc->sc_base_addr) {
  20426. + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
  20427. + mem_start, mem_start + mem_len - 1);
  20428. + goto out;
  20429. + }
  20430. +
  20431. + /* fix up the bus size */
  20432. + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  20433. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  20434. + goto out;
  20435. + }
  20436. + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  20437. + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
  20438. + goto out;
  20439. + }
  20440. +
  20441. + pci_set_master(sc->sc_pcidev);
  20442. +
  20443. + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
  20444. +
  20445. + if (!(cmd & PCI_COMMAND_MEMORY)) {
  20446. + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
  20447. + goto out;
  20448. + }
  20449. +
  20450. + if (!(cmd & PCI_COMMAND_MASTER)) {
  20451. + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
  20452. + goto out;
  20453. + }
  20454. +
  20455. + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
  20456. + if (rc) {
  20457. + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
  20458. + goto out;
  20459. + }
  20460. + sc->sc_irq = dev->irq;
  20461. +
  20462. + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
  20463. + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
  20464. +
  20465. + /*
  20466. + * Allocate packet engine descriptors.
  20467. + */
  20468. + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  20469. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  20470. + &sc->sc_ringalloc.dma_paddr);
  20471. + if (!sc->sc_ringalloc.dma_vaddr) {
  20472. + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
  20473. + goto out;
  20474. + }
  20475. +
  20476. + /*
  20477. + * Hookup the static portion of all our data structures.
  20478. + */
  20479. + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
  20480. + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
  20481. + sc->sc_front = sc->sc_ring;
  20482. + sc->sc_back = sc->sc_ring;
  20483. + raddr = sc->sc_ringalloc.dma_paddr;
  20484. + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
  20485. + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
  20486. + struct safe_ringentry *re = &sc->sc_ring[i];
  20487. +
  20488. + re->re_desc.d_sa = raddr +
  20489. + offsetof(struct safe_ringentry, re_sa);
  20490. + re->re_sa.sa_staterec = raddr +
  20491. + offsetof(struct safe_ringentry, re_sastate);
  20492. +
  20493. + raddr += sizeof (struct safe_ringentry);
  20494. + }
  20495. + spin_lock_init(&sc->sc_ringmtx);
  20496. +
  20497. + /*
  20498. + * Allocate scatter and gather particle descriptors.
  20499. + */
  20500. + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  20501. + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
  20502. + &sc->sc_spalloc.dma_paddr);
  20503. + if (!sc->sc_spalloc.dma_vaddr) {
  20504. + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
  20505. + goto out;
  20506. + }
  20507. + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
  20508. + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
  20509. + sc->sc_spfree = sc->sc_spring;
  20510. + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
  20511. +
  20512. + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  20513. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20514. + &sc->sc_dpalloc.dma_paddr);
  20515. + if (!sc->sc_dpalloc.dma_vaddr) {
  20516. + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
  20517. + goto out;
  20518. + }
  20519. + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
  20520. + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
  20521. + sc->sc_dpfree = sc->sc_dpring;
  20522. + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
  20523. +
  20524. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
  20525. + if (sc->sc_cid < 0) {
  20526. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  20527. + goto out;
  20528. + }
  20529. +
  20530. + printf("%s:", device_get_nameunit(sc->sc_dev));
  20531. +
  20532. + devinfo = READ_REG(sc, SAFE_DEVINFO);
  20533. + if (devinfo & SAFE_DEVINFO_RNG) {
  20534. + sc->sc_flags |= SAFE_FLAGS_RNG;
  20535. + printf(" rng");
  20536. + }
  20537. + if (devinfo & SAFE_DEVINFO_PKEY) {
  20538. + printf(" key");
  20539. + sc->sc_flags |= SAFE_FLAGS_KEY;
  20540. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
  20541. +#if 0
  20542. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
  20543. +#endif
  20544. + init_timer(&sc->sc_pkto);
  20545. + sc->sc_pkto.function = safe_kpoll;
  20546. + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
  20547. + }
  20548. + if (devinfo & SAFE_DEVINFO_DES) {
  20549. + printf(" des/3des");
  20550. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  20551. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  20552. + }
  20553. + if (devinfo & SAFE_DEVINFO_AES) {
  20554. + printf(" aes");
  20555. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  20556. + }
  20557. + if (devinfo & SAFE_DEVINFO_MD5) {
  20558. + printf(" md5");
  20559. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  20560. + }
  20561. + if (devinfo & SAFE_DEVINFO_SHA1) {
  20562. + printf(" sha1");
  20563. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  20564. + }
  20565. + printf(" null");
  20566. + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
  20567. + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
  20568. + /* XXX other supported algorithms */
  20569. + printf("\n");
  20570. +
  20571. + safe_reset_board(sc); /* reset h/w */
  20572. + safe_init_board(sc); /* init h/w */
  20573. +
  20574. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  20575. + if (sc->sc_flags & SAFE_FLAGS_RNG) {
  20576. + safe_rng_init(sc);
  20577. + crypto_rregister(sc->sc_cid, safe_read_random, sc);
  20578. + }
  20579. +#endif /* SAFE_NO_RNG */
  20580. +
  20581. + return (0);
  20582. +
  20583. +out:
  20584. + if (sc->sc_cid >= 0)
  20585. + crypto_unregister_all(sc->sc_cid);
  20586. + if (sc->sc_irq != -1)
  20587. + free_irq(sc->sc_irq, sc);
  20588. + if (sc->sc_ringalloc.dma_vaddr)
  20589. + pci_free_consistent(sc->sc_pcidev,
  20590. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  20591. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  20592. + if (sc->sc_spalloc.dma_vaddr)
  20593. + pci_free_consistent(sc->sc_pcidev,
  20594. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20595. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  20596. + if (sc->sc_dpalloc.dma_vaddr)
  20597. + pci_free_consistent(sc->sc_pcidev,
  20598. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20599. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  20600. + kfree(sc);
  20601. + return(-ENODEV);
  20602. +}
  20603. +
  20604. +static void safe_remove(struct pci_dev *dev)
  20605. +{
  20606. + struct safe_softc *sc = pci_get_drvdata(dev);
  20607. +
  20608. + DPRINTF(("%s()\n", __FUNCTION__));
  20609. +
  20610. + /* XXX wait/abort active ops */
  20611. +
  20612. + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
  20613. +
  20614. + del_timer_sync(&sc->sc_pkto);
  20615. +
  20616. + crypto_unregister_all(sc->sc_cid);
  20617. +
  20618. + safe_cleanchip(sc);
  20619. +
  20620. + if (sc->sc_irq != -1)
  20621. + free_irq(sc->sc_irq, sc);
  20622. + if (sc->sc_ringalloc.dma_vaddr)
  20623. + pci_free_consistent(sc->sc_pcidev,
  20624. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  20625. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  20626. + if (sc->sc_spalloc.dma_vaddr)
  20627. + pci_free_consistent(sc->sc_pcidev,
  20628. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20629. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  20630. + if (sc->sc_dpalloc.dma_vaddr)
  20631. + pci_free_consistent(sc->sc_pcidev,
  20632. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  20633. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  20634. + sc->sc_irq = -1;
  20635. + sc->sc_ringalloc.dma_vaddr = NULL;
  20636. + sc->sc_spalloc.dma_vaddr = NULL;
  20637. + sc->sc_dpalloc.dma_vaddr = NULL;
  20638. +}
  20639. +
  20640. +static struct pci_device_id safe_pci_tbl[] = {
  20641. + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
  20642. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  20643. + { },
  20644. +};
  20645. +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
  20646. +
  20647. +static struct pci_driver safe_driver = {
  20648. + .name = "safe",
  20649. + .id_table = safe_pci_tbl,
  20650. + .probe = safe_probe,
  20651. + .remove = safe_remove,
  20652. + /* add PM stuff here one day */
  20653. +};
  20654. +
  20655. +static int __init safe_init (void)
  20656. +{
  20657. + struct safe_softc *sc = NULL;
  20658. + int rc;
  20659. +
  20660. + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
  20661. +
  20662. + rc = pci_register_driver(&safe_driver);
  20663. + pci_register_driver_compat(&safe_driver, rc);
  20664. +
  20665. + return rc;
  20666. +}
  20667. +
  20668. +static void __exit safe_exit (void)
  20669. +{
  20670. + pci_unregister_driver(&safe_driver);
  20671. +}
  20672. +
  20673. +module_init(safe_init);
  20674. +module_exit(safe_exit);
  20675. +
  20676. +MODULE_LICENSE("BSD");
  20677. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  20678. +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
  20679. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/safereg.h linux-2.6.29.1/crypto/ocf/safe/safereg.h
  20680. --- linux-2.6.29.1.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
  20681. +++ linux-2.6.29.1/crypto/ocf/safe/safereg.h 2009-04-20 20:01:21.624562844 +0200
  20682. @@ -0,0 +1,421 @@
  20683. +/*-
  20684. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  20685. + * Copyright (c) 2003 Global Technology Associates, Inc.
  20686. + * All rights reserved.
  20687. + *
  20688. + * Redistribution and use in source and binary forms, with or without
  20689. + * modification, are permitted provided that the following conditions
  20690. + * are met:
  20691. + * 1. Redistributions of source code must retain the above copyright
  20692. + * notice, this list of conditions and the following disclaimer.
  20693. + * 2. Redistributions in binary form must reproduce the above copyright
  20694. + * notice, this list of conditions and the following disclaimer in the
  20695. + * documentation and/or other materials provided with the distribution.
  20696. + *
  20697. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20698. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20699. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20700. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20701. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20702. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20703. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20704. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  20705. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  20706. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  20707. + * SUCH DAMAGE.
  20708. + *
  20709. + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
  20710. + */
  20711. +#ifndef _SAFE_SAFEREG_H_
  20712. +#define _SAFE_SAFEREG_H_
  20713. +
  20714. +/*
  20715. + * Register definitions for SafeNet SafeXcel-1141 crypto device.
  20716. + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
  20717. + */
  20718. +
  20719. +#define BS_BAR 0x10 /* DMA base address register */
  20720. +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
  20721. +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
  20722. +
  20723. +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
  20724. +
  20725. +/* SafeNet */
  20726. +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
  20727. +
  20728. +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
  20729. +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
  20730. +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
  20731. +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
  20732. +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
  20733. +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
  20734. +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
  20735. +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
  20736. +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
  20737. +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
  20738. +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
  20739. +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
  20740. +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
  20741. +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
  20742. +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
  20743. +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
  20744. +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
  20745. +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
  20746. +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
  20747. +#define SAFE_DEVID 0x0084 /* Device ID */
  20748. +#define SAFE_DEVINFO 0x0088 /* Device Info */
  20749. +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
  20750. +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
  20751. +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
  20752. +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
  20753. +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
  20754. +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
  20755. +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
  20756. +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
  20757. +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
  20758. +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
  20759. +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
  20760. +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
  20761. +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
  20762. +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
  20763. +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
  20764. +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
  20765. +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
  20766. +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
  20767. +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
  20768. +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
  20769. +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
  20770. +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
  20771. +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
  20772. +
  20773. +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
  20774. +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
  20775. +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
  20776. +#define SAFE_RNG_A 0x010c /* RNG A */
  20777. +#define SAFE_RNG_B 0x0110 /* RNG B */
  20778. +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
  20779. +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
  20780. +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
  20781. +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
  20782. +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
  20783. +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
  20784. +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
  20785. +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
  20786. +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
  20787. +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
  20788. +
  20789. +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
  20790. +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
  20791. +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
  20792. +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
  20793. +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
  20794. +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
  20795. +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
  20796. +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
  20797. +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
  20798. +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
  20799. +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
  20800. +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
  20801. +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
  20802. +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
  20803. +#define SAFE_PE_CSR_XECODE_S 20
  20804. +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
  20805. +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
  20806. +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
  20807. +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
  20808. +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
  20809. +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
  20810. +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
  20811. +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
  20812. +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
  20813. +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
  20814. +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
  20815. +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
  20816. +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
  20817. +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
  20818. +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
  20819. +
  20820. +/*
  20821. + * Check the CSR to see if the PE has returned ownership to
  20822. + * the host. Note that before processing a descriptor this
  20823. + * must be done followed by a check of the SAFE_PE_LEN register
  20824. + * status bits to avoid premature processing of a descriptor
  20825. + * on its way back to the host.
  20826. + */
  20827. +#define SAFE_PE_CSR_IS_DONE(_csr) \
  20828. + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
  20829. +
  20830. +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
  20831. +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
  20832. +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
  20833. +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
  20834. +#define SAFE_PE_LEN_BYPASS_S 24
  20835. +
  20836. +#define SAFE_PE_LEN_IS_DONE(_len) \
  20837. + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
  20838. +
  20839. +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
  20840. +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
  20841. +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
  20842. +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
  20843. +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
  20844. +
  20845. +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
  20846. +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
  20847. +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
  20848. +
  20849. +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
  20850. +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
  20851. +
  20852. +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
  20853. +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
  20854. +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
  20855. +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
  20856. +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
  20857. +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
  20858. +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
  20859. +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
  20860. +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
  20861. +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
  20862. +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
  20863. +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
  20864. +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
  20865. +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
  20866. +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
  20867. +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
  20868. +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
  20869. +
  20870. +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
  20871. +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
  20872. +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
  20873. +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
  20874. +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
  20875. +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
  20876. +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
  20877. +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
  20878. +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
  20879. +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
  20880. +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
  20881. +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
  20882. +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
  20883. +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
  20884. +
  20885. +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
  20886. +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
  20887. +#define SAFE_PE_RINGCFG_OFFSET_S 16
  20888. +
  20889. +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
  20890. +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
  20891. +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
  20892. +
  20893. +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
  20894. +
  20895. +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
  20896. +#define SAFE_PE_ERNGSTAT_NEXT_S 16
  20897. +
  20898. +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
  20899. +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
  20900. +
  20901. +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
  20902. +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
  20903. +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
  20904. +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
  20905. +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
  20906. +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
  20907. +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
  20908. +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
  20909. +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
  20910. +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
  20911. +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
  20912. +
  20913. +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
  20914. +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
  20915. +
  20916. +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
  20917. +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
  20918. +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
  20919. +
  20920. +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
  20921. +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
  20922. +#define SAFE_DEVINFO_REV_MAJ_S 4
  20923. +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
  20924. +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
  20925. +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
  20926. +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
  20927. +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
  20928. +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
  20929. +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
  20930. +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
  20931. +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
  20932. +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
  20933. +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
  20934. +
  20935. +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
  20936. +#define SAFE_REV_MAJ(_chiprev) \
  20937. + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
  20938. +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
  20939. +
  20940. +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
  20941. +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
  20942. +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
  20943. +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
  20944. +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
  20945. +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
  20946. +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
  20947. +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
  20948. +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
  20949. +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
  20950. +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
  20951. +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
  20952. +
  20953. +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
  20954. +
  20955. +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
  20956. +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
  20957. +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
  20958. +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
  20959. +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
  20960. +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
  20961. +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
  20962. +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
  20963. +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
  20964. +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
  20965. +
  20966. +/*
  20967. + * Packet engine descriptor. Note that d_csr is a copy of the
  20968. + * SAFE_PE_CSR register and all definitions apply, and d_len
  20969. + * is a copy of the SAFE_PE_LEN register and all definitions apply.
  20970. + * d_src and d_len may point directly to contiguous data or to a
  20971. + * list of ``particle descriptors'' when using scatter/gather i/o.
  20972. + */
  20973. +struct safe_desc {
  20974. + u_int32_t d_csr; /* per-packet control/status */
  20975. + u_int32_t d_src; /* source address */
  20976. + u_int32_t d_dst; /* destination address */
  20977. + u_int32_t d_sa; /* SA address */
  20978. + u_int32_t d_len; /* length, bypass, status */
  20979. +};
  20980. +
  20981. +/*
  20982. + * Scatter/Gather particle descriptor.
  20983. + *
  20984. + * NB: scatter descriptors do not specify a size; this is fixed
  20985. + * by the setting of the SAFE_PE_PARTCFG register.
  20986. + */
  20987. +struct safe_pdesc {
  20988. + u_int32_t pd_addr; /* particle address */
  20989. +#ifdef __BIG_ENDIAN
  20990. + u_int16_t pd_flags; /* control word */
  20991. + u_int16_t pd_size; /* particle size (bytes) */
  20992. +#else
  20993. + u_int16_t pd_flags; /* control word */
  20994. + u_int16_t pd_size; /* particle size (bytes) */
  20995. +#endif
  20996. +};
  20997. +
  20998. +#define SAFE_PD_READY 0x0001 /* ready for processing */
  20999. +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
  21000. +
  21001. +/*
  21002. + * Security Association (SA) Record (Rev 1). One of these is
  21003. + * required for each operation processed by the packet engine.
  21004. + */
  21005. +struct safe_sarec {
  21006. + u_int32_t sa_cmd0;
  21007. + u_int32_t sa_cmd1;
  21008. + u_int32_t sa_resv0;
  21009. + u_int32_t sa_resv1;
  21010. + u_int32_t sa_key[8]; /* DES/3DES/AES key */
  21011. + u_int32_t sa_indigest[5]; /* inner digest */
  21012. + u_int32_t sa_outdigest[5]; /* outer digest */
  21013. + u_int32_t sa_spi; /* SPI */
  21014. + u_int32_t sa_seqnum; /* sequence number */
  21015. + u_int32_t sa_seqmask[2]; /* sequence number mask */
  21016. + u_int32_t sa_resv2;
  21017. + u_int32_t sa_staterec; /* address of state record */
  21018. + u_int32_t sa_resv3[2];
  21019. + u_int32_t sa_samgmt0; /* SA management field 0 */
  21020. + u_int32_t sa_samgmt1; /* SA management field 0 */
  21021. +};
  21022. +
  21023. +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
  21024. +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
  21025. +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
  21026. +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
  21027. +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
  21028. +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
  21029. +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
  21030. +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
  21031. +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
  21032. +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
  21033. +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
  21034. +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
  21035. +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
  21036. +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
  21037. +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
  21038. +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
  21039. +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
  21040. +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
  21041. +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
  21042. +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
  21043. +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
  21044. +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
  21045. +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
  21046. +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
  21047. +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
  21048. +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
  21049. +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
  21050. +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
  21051. +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
  21052. +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
  21053. +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
  21054. +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
  21055. +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
  21056. +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
  21057. +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
  21058. +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
  21059. +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
  21060. +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
  21061. +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
  21062. +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
  21063. +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
  21064. +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
  21065. +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
  21066. +
  21067. +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
  21068. +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
  21069. +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
  21070. +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
  21071. +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
  21072. +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
  21073. +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
  21074. +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
  21075. +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
  21076. +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
  21077. +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
  21078. +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
  21079. +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
  21080. +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
  21081. +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
  21082. +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
  21083. +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
  21084. +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
  21085. +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
  21086. +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
  21087. +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
  21088. +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
  21089. +#define SAFE_SA_CMD1_OFFSET_S 16
  21090. +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
  21091. +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
  21092. +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
  21093. +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
  21094. +
  21095. +/*
  21096. + * Security Associate State Record (Rev 1).
  21097. + */
  21098. +struct safe_sastate {
  21099. + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
  21100. + u_int32_t sa_saved_hashbc; /* saved hash byte count */
  21101. + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
  21102. +};
  21103. +#endif /* _SAFE_SAFEREG_H_ */
  21104. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/safevar.h linux-2.6.29.1/crypto/ocf/safe/safevar.h
  21105. --- linux-2.6.29.1.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
  21106. +++ linux-2.6.29.1/crypto/ocf/safe/safevar.h 2009-04-20 20:01:21.624562844 +0200
  21107. @@ -0,0 +1,230 @@
  21108. +/*-
  21109. + * The linux port of this code done by David McCullough
  21110. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
  21111. + * The license and original author are listed below.
  21112. + *
  21113. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  21114. + * Copyright (c) 2003 Global Technology Associates, Inc.
  21115. + * All rights reserved.
  21116. + *
  21117. + * Redistribution and use in source and binary forms, with or without
  21118. + * modification, are permitted provided that the following conditions
  21119. + * are met:
  21120. + * 1. Redistributions of source code must retain the above copyright
  21121. + * notice, this list of conditions and the following disclaimer.
  21122. + * 2. Redistributions in binary form must reproduce the above copyright
  21123. + * notice, this list of conditions and the following disclaimer in the
  21124. + * documentation and/or other materials provided with the distribution.
  21125. + *
  21126. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  21127. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21128. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21129. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21130. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21131. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21132. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21133. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21134. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21135. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  21136. + * SUCH DAMAGE.
  21137. + *
  21138. + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
  21139. + */
  21140. +#ifndef _SAFE_SAFEVAR_H_
  21141. +#define _SAFE_SAFEVAR_H_
  21142. +
  21143. +/* Maximum queue length */
  21144. +#ifndef SAFE_MAX_NQUEUE
  21145. +#define SAFE_MAX_NQUEUE 60
  21146. +#endif
  21147. +
  21148. +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
  21149. +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
  21150. +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
  21151. +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
  21152. +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
  21153. +/* total src+dst particle descriptors */
  21154. +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  21155. +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  21156. +
  21157. +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
  21158. +
  21159. +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
  21160. +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
  21161. +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  21162. +
  21163. +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
  21164. +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
  21165. +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
  21166. +
  21167. +#ifdef __KERNEL__
  21168. +/*
  21169. + * State associated with the allocation of each chunk
  21170. + * of memory setup for DMA.
  21171. + */
  21172. +struct safe_dma_alloc {
  21173. + dma_addr_t dma_paddr;
  21174. + void *dma_vaddr;
  21175. +};
  21176. +
  21177. +/*
  21178. + * Cryptographic operand state. One of these exists for each
  21179. + * source and destination operand passed in from the crypto
  21180. + * subsystem. When possible source and destination operands
  21181. + * refer to the same memory. More often they are distinct.
  21182. + * We track the virtual address of each operand as well as
  21183. + * where each is mapped for DMA.
  21184. + */
  21185. +struct safe_operand {
  21186. + union {
  21187. + struct sk_buff *skb;
  21188. + struct uio *io;
  21189. + } u;
  21190. + void *map;
  21191. + int mapsize; /* total number of bytes in segs */
  21192. + struct {
  21193. + dma_addr_t ds_addr;
  21194. + int ds_len;
  21195. + int ds_tlen;
  21196. + } segs[SAFE_MAX_PART];
  21197. + int nsegs;
  21198. +};
  21199. +
  21200. +/*
  21201. + * Packet engine ring entry and cryptographic operation state.
  21202. + * The packet engine requires a ring of descriptors that contain
  21203. + * pointers to various cryptographic state. However the ring
  21204. + * configuration register allows you to specify an arbitrary size
  21205. + * for ring entries. We use this feature to collect most of the
  21206. + * state for each cryptographic request into one spot. Other than
  21207. + * ring entries only the ``particle descriptors'' (scatter/gather
  21208. + * lists) and the actual operand data are kept separate. The
  21209. + * particle descriptors must also be organized in rings. The
  21210. + * operand data can be located aribtrarily (modulo alignment constraints).
  21211. + *
  21212. + * Note that the descriptor ring is mapped onto the PCI bus so
  21213. + * the hardware can DMA data. This means the entire ring must be
  21214. + * contiguous.
  21215. + */
  21216. +struct safe_ringentry {
  21217. + struct safe_desc re_desc; /* command descriptor */
  21218. + struct safe_sarec re_sa; /* SA record */
  21219. + struct safe_sastate re_sastate; /* SA state record */
  21220. +
  21221. + struct cryptop *re_crp; /* crypto operation */
  21222. +
  21223. + struct safe_operand re_src; /* source operand */
  21224. + struct safe_operand re_dst; /* destination operand */
  21225. +
  21226. + int re_sesn; /* crypto session ID */
  21227. + int re_flags;
  21228. +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
  21229. +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
  21230. +};
  21231. +
  21232. +#define re_src_skb re_src.u.skb
  21233. +#define re_src_io re_src.u.io
  21234. +#define re_src_map re_src.map
  21235. +#define re_src_nsegs re_src.nsegs
  21236. +#define re_src_segs re_src.segs
  21237. +#define re_src_mapsize re_src.mapsize
  21238. +
  21239. +#define re_dst_skb re_dst.u.skb
  21240. +#define re_dst_io re_dst.u.io
  21241. +#define re_dst_map re_dst.map
  21242. +#define re_dst_nsegs re_dst.nsegs
  21243. +#define re_dst_segs re_dst.segs
  21244. +#define re_dst_mapsize re_dst.mapsize
  21245. +
  21246. +struct rndstate_test;
  21247. +
  21248. +struct safe_session {
  21249. + u_int32_t ses_used;
  21250. + u_int32_t ses_klen; /* key length in bits */
  21251. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  21252. + u_int32_t ses_mlen; /* hmac length in bytes */
  21253. + u_int32_t ses_hminner[5]; /* hmac inner state */
  21254. + u_int32_t ses_hmouter[5]; /* hmac outer state */
  21255. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  21256. +};
  21257. +
  21258. +struct safe_pkq {
  21259. + struct list_head pkq_list;
  21260. + struct cryptkop *pkq_krp;
  21261. +};
  21262. +
  21263. +struct safe_softc {
  21264. + softc_device_decl sc_dev;
  21265. + u32 sc_irq;
  21266. +
  21267. + struct pci_dev *sc_pcidev;
  21268. + ocf_iomem_t sc_base_addr;
  21269. +
  21270. + u_int sc_chiprev; /* major/minor chip revision */
  21271. + int sc_flags; /* device specific flags */
  21272. +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
  21273. +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
  21274. + int sc_suspended;
  21275. + int sc_needwakeup; /* notify crypto layer */
  21276. + int32_t sc_cid; /* crypto tag */
  21277. +
  21278. + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
  21279. + struct safe_ringentry *sc_ring; /* PE ring */
  21280. + struct safe_ringentry *sc_ringtop; /* PE ring top */
  21281. + struct safe_ringentry *sc_front; /* next free entry */
  21282. + struct safe_ringentry *sc_back; /* next pending entry */
  21283. + int sc_nqchip; /* # passed to chip */
  21284. + spinlock_t sc_ringmtx; /* PE ring lock */
  21285. + struct safe_pdesc *sc_spring; /* src particle ring */
  21286. + struct safe_pdesc *sc_springtop; /* src particle ring top */
  21287. + struct safe_pdesc *sc_spfree; /* next free src particle */
  21288. + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
  21289. + struct safe_pdesc *sc_dpring; /* dest particle ring */
  21290. + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
  21291. + struct safe_pdesc *sc_dpfree; /* next free dest particle */
  21292. + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
  21293. + int sc_nsessions; /* # of sessions */
  21294. + struct safe_session *sc_sessions; /* sessions */
  21295. +
  21296. + struct timer_list sc_pkto; /* PK polling */
  21297. + spinlock_t sc_pkmtx; /* PK lock */
  21298. + struct list_head sc_pkq; /* queue of PK requests */
  21299. + struct safe_pkq *sc_pkq_cur; /* current processing request */
  21300. + u_int32_t sc_pk_reslen, sc_pk_resoff;
  21301. +
  21302. + int sc_max_dsize; /* maximum safe DMA size */
  21303. +};
  21304. +#endif /* __KERNEL__ */
  21305. +
  21306. +struct safe_stats {
  21307. + u_int64_t st_ibytes;
  21308. + u_int64_t st_obytes;
  21309. + u_int32_t st_ipackets;
  21310. + u_int32_t st_opackets;
  21311. + u_int32_t st_invalid; /* invalid argument */
  21312. + u_int32_t st_badsession; /* invalid session id */
  21313. + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
  21314. + u_int32_t st_nodesc; /* op submitted w/o descriptors */
  21315. + u_int32_t st_badalg; /* unsupported algorithm */
  21316. + u_int32_t st_ringfull; /* PE descriptor ring full */
  21317. + u_int32_t st_peoperr; /* PE marked error */
  21318. + u_int32_t st_dmaerr; /* PE DMA error */
  21319. + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
  21320. + u_int32_t st_skipmismatch; /* enc part begins before auth part */
  21321. + u_int32_t st_lenmismatch; /* enc length different auth length */
  21322. + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
  21323. + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
  21324. + u_int32_t st_iovmisaligned; /* iov op not aligned */
  21325. + u_int32_t st_iovnotuniform; /* iov op not suitable */
  21326. + u_int32_t st_unaligned; /* unaligned src caused copy */
  21327. + u_int32_t st_notuniform; /* non-uniform src caused copy */
  21328. + u_int32_t st_nomap; /* bus_dmamap_create failed */
  21329. + u_int32_t st_noload; /* bus_dmamap_load_* failed */
  21330. + u_int32_t st_nombuf; /* MGET* failed */
  21331. + u_int32_t st_nomcl; /* MCLGET* failed */
  21332. + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
  21333. + u_int32_t st_rng; /* RNG requests */
  21334. + u_int32_t st_rngalarm; /* RNG alarm requests */
  21335. + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
  21336. +};
  21337. +#endif /* _SAFE_SAFEVAR_H_ */
  21338. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/sha1.c linux-2.6.29.1/crypto/ocf/safe/sha1.c
  21339. --- linux-2.6.29.1.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
  21340. +++ linux-2.6.29.1/crypto/ocf/safe/sha1.c 2009-04-20 20:01:21.628563633 +0200
  21341. @@ -0,0 +1,279 @@
  21342. +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  21343. +/*
  21344. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  21345. + * All rights reserved.
  21346. + *
  21347. + * Redistribution and use in source and binary forms, with or without
  21348. + * modification, are permitted provided that the following conditions
  21349. + * are met:
  21350. + * 1. Redistributions of source code must retain the above copyright
  21351. + * notice, this list of conditions and the following disclaimer.
  21352. + * 2. Redistributions in binary form must reproduce the above copyright
  21353. + * notice, this list of conditions and the following disclaimer in the
  21354. + * documentation and/or other materials provided with the distribution.
  21355. + * 3. Neither the name of the project nor the names of its contributors
  21356. + * may be used to endorse or promote products derived from this software
  21357. + * without specific prior written permission.
  21358. + *
  21359. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  21360. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21361. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21362. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  21363. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21364. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21365. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21366. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21367. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21368. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  21369. + * SUCH DAMAGE.
  21370. + */
  21371. +
  21372. +/*
  21373. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  21374. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  21375. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  21376. + */
  21377. +
  21378. +#if 0
  21379. +#include <sys/cdefs.h>
  21380. +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
  21381. +
  21382. +#include <sys/types.h>
  21383. +#include <sys/cdefs.h>
  21384. +#include <sys/time.h>
  21385. +#include <sys/systm.h>
  21386. +
  21387. +#include <crypto/sha1.h>
  21388. +#endif
  21389. +
  21390. +/* sanity check */
  21391. +#if BYTE_ORDER != BIG_ENDIAN
  21392. +# if BYTE_ORDER != LITTLE_ENDIAN
  21393. +# define unsupported 1
  21394. +# endif
  21395. +#endif
  21396. +
  21397. +#ifndef unsupported
  21398. +
  21399. +/* constant table */
  21400. +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
  21401. +#define K(t) _K[(t) / 20]
  21402. +
  21403. +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
  21404. +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
  21405. +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  21406. +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
  21407. +
  21408. +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
  21409. +
  21410. +#undef H
  21411. +#define H(n) (ctxt->h.b32[(n)])
  21412. +#define COUNT (ctxt->count)
  21413. +#define BCOUNT (ctxt->c.b64[0] / 8)
  21414. +#define W(n) (ctxt->m.b32[(n)])
  21415. +
  21416. +#define PUTBYTE(x) { \
  21417. + ctxt->m.b8[(COUNT % 64)] = (x); \
  21418. + COUNT++; \
  21419. + COUNT %= 64; \
  21420. + ctxt->c.b64[0] += 8; \
  21421. + if (COUNT % 64 == 0) \
  21422. + sha1_step(ctxt); \
  21423. + }
  21424. +
  21425. +#define PUTPAD(x) { \
  21426. + ctxt->m.b8[(COUNT % 64)] = (x); \
  21427. + COUNT++; \
  21428. + COUNT %= 64; \
  21429. + if (COUNT % 64 == 0) \
  21430. + sha1_step(ctxt); \
  21431. + }
  21432. +
  21433. +static void sha1_step(struct sha1_ctxt *);
  21434. +
  21435. +static void
  21436. +sha1_step(ctxt)
  21437. + struct sha1_ctxt *ctxt;
  21438. +{
  21439. + u_int32_t a, b, c, d, e;
  21440. + size_t t, s;
  21441. + u_int32_t tmp;
  21442. +
  21443. +#if BYTE_ORDER == LITTLE_ENDIAN
  21444. + struct sha1_ctxt tctxt;
  21445. + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
  21446. + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
  21447. + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
  21448. + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
  21449. + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
  21450. + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
  21451. + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
  21452. + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
  21453. + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
  21454. + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
  21455. + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
  21456. + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
  21457. + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
  21458. + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
  21459. + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
  21460. + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
  21461. + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
  21462. + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
  21463. + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
  21464. + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
  21465. + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
  21466. + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
  21467. + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
  21468. + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
  21469. + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
  21470. + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
  21471. + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
  21472. + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
  21473. + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
  21474. + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
  21475. + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
  21476. + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
  21477. + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
  21478. +#endif
  21479. +
  21480. + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
  21481. +
  21482. + for (t = 0; t < 20; t++) {
  21483. + s = t & 0x0f;
  21484. + if (t >= 16) {
  21485. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21486. + }
  21487. + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
  21488. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21489. + }
  21490. + for (t = 20; t < 40; t++) {
  21491. + s = t & 0x0f;
  21492. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21493. + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
  21494. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21495. + }
  21496. + for (t = 40; t < 60; t++) {
  21497. + s = t & 0x0f;
  21498. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21499. + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
  21500. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21501. + }
  21502. + for (t = 60; t < 80; t++) {
  21503. + s = t & 0x0f;
  21504. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  21505. + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
  21506. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  21507. + }
  21508. +
  21509. + H(0) = H(0) + a;
  21510. + H(1) = H(1) + b;
  21511. + H(2) = H(2) + c;
  21512. + H(3) = H(3) + d;
  21513. + H(4) = H(4) + e;
  21514. +
  21515. + bzero(&ctxt->m.b8[0], 64);
  21516. +}
  21517. +
  21518. +/*------------------------------------------------------------*/
  21519. +
  21520. +void
  21521. +sha1_init(ctxt)
  21522. + struct sha1_ctxt *ctxt;
  21523. +{
  21524. + bzero(ctxt, sizeof(struct sha1_ctxt));
  21525. + H(0) = 0x67452301;
  21526. + H(1) = 0xefcdab89;
  21527. + H(2) = 0x98badcfe;
  21528. + H(3) = 0x10325476;
  21529. + H(4) = 0xc3d2e1f0;
  21530. +}
  21531. +
  21532. +void
  21533. +sha1_pad(ctxt)
  21534. + struct sha1_ctxt *ctxt;
  21535. +{
  21536. + size_t padlen; /*pad length in bytes*/
  21537. + size_t padstart;
  21538. +
  21539. + PUTPAD(0x80);
  21540. +
  21541. + padstart = COUNT % 64;
  21542. + padlen = 64 - padstart;
  21543. + if (padlen < 8) {
  21544. + bzero(&ctxt->m.b8[padstart], padlen);
  21545. + COUNT += padlen;
  21546. + COUNT %= 64;
  21547. + sha1_step(ctxt);
  21548. + padstart = COUNT % 64; /* should be 0 */
  21549. + padlen = 64 - padstart; /* should be 64 */
  21550. + }
  21551. + bzero(&ctxt->m.b8[padstart], padlen - 8);
  21552. + COUNT += (padlen - 8);
  21553. + COUNT %= 64;
  21554. +#if BYTE_ORDER == BIG_ENDIAN
  21555. + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
  21556. + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
  21557. + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
  21558. + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
  21559. +#else
  21560. + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
  21561. + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
  21562. + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
  21563. + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
  21564. +#endif
  21565. +}
  21566. +
  21567. +void
  21568. +sha1_loop(ctxt, input, len)
  21569. + struct sha1_ctxt *ctxt;
  21570. + const u_int8_t *input;
  21571. + size_t len;
  21572. +{
  21573. + size_t gaplen;
  21574. + size_t gapstart;
  21575. + size_t off;
  21576. + size_t copysiz;
  21577. +
  21578. + off = 0;
  21579. +
  21580. + while (off < len) {
  21581. + gapstart = COUNT % 64;
  21582. + gaplen = 64 - gapstart;
  21583. +
  21584. + copysiz = (gaplen < len - off) ? gaplen : len - off;
  21585. + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
  21586. + COUNT += copysiz;
  21587. + COUNT %= 64;
  21588. + ctxt->c.b64[0] += copysiz * 8;
  21589. + if (COUNT % 64 == 0)
  21590. + sha1_step(ctxt);
  21591. + off += copysiz;
  21592. + }
  21593. +}
  21594. +
  21595. +void
  21596. +sha1_result(ctxt, digest0)
  21597. + struct sha1_ctxt *ctxt;
  21598. + caddr_t digest0;
  21599. +{
  21600. + u_int8_t *digest;
  21601. +
  21602. + digest = (u_int8_t *)digest0;
  21603. + sha1_pad(ctxt);
  21604. +#if BYTE_ORDER == BIG_ENDIAN
  21605. + bcopy(&ctxt->h.b8[0], digest, 20);
  21606. +#else
  21607. + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
  21608. + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
  21609. + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
  21610. + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
  21611. + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
  21612. + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
  21613. + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
  21614. + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
  21615. + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
  21616. + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
  21617. +#endif
  21618. +}
  21619. +
  21620. +#endif /*unsupported*/
  21621. diff -Nur linux-2.6.29.1.orig/crypto/ocf/safe/sha1.h linux-2.6.29.1/crypto/ocf/safe/sha1.h
  21622. --- linux-2.6.29.1.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
  21623. +++ linux-2.6.29.1/crypto/ocf/safe/sha1.h 2009-04-20 20:01:21.628563633 +0200
  21624. @@ -0,0 +1,72 @@
  21625. +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
  21626. +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
  21627. +
  21628. +/*
  21629. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  21630. + * All rights reserved.
  21631. + *
  21632. + * Redistribution and use in source and binary forms, with or without
  21633. + * modification, are permitted provided that the following conditions
  21634. + * are met:
  21635. + * 1. Redistributions of source code must retain the above copyright
  21636. + * notice, this list of conditions and the following disclaimer.
  21637. + * 2. Redistributions in binary form must reproduce the above copyright
  21638. + * notice, this list of conditions and the following disclaimer in the
  21639. + * documentation and/or other materials provided with the distribution.
  21640. + * 3. Neither the name of the project nor the names of its contributors
  21641. + * may be used to endorse or promote products derived from this software
  21642. + * without specific prior written permission.
  21643. + *
  21644. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  21645. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21646. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21647. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  21648. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21649. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  21650. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21651. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21652. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21653. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  21654. + * SUCH DAMAGE.
  21655. + */
  21656. +/*
  21657. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  21658. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  21659. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  21660. + */
  21661. +
  21662. +#ifndef _NETINET6_SHA1_H_
  21663. +#define _NETINET6_SHA1_H_
  21664. +
  21665. +struct sha1_ctxt {
  21666. + union {
  21667. + u_int8_t b8[20];
  21668. + u_int32_t b32[5];
  21669. + } h;
  21670. + union {
  21671. + u_int8_t b8[8];
  21672. + u_int64_t b64[1];
  21673. + } c;
  21674. + union {
  21675. + u_int8_t b8[64];
  21676. + u_int32_t b32[16];
  21677. + } m;
  21678. + u_int8_t count;
  21679. +};
  21680. +
  21681. +#ifdef __KERNEL__
  21682. +extern void sha1_init(struct sha1_ctxt *);
  21683. +extern void sha1_pad(struct sha1_ctxt *);
  21684. +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
  21685. +extern void sha1_result(struct sha1_ctxt *, caddr_t);
  21686. +
  21687. +/* compatibilty with other SHA1 source codes */
  21688. +typedef struct sha1_ctxt SHA1_CTX;
  21689. +#define SHA1Init(x) sha1_init((x))
  21690. +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
  21691. +#define SHA1Final(x, y) sha1_result((y), (x))
  21692. +#endif /* __KERNEL__ */
  21693. +
  21694. +#define SHA1_RESULTLEN (160/8)
  21695. +
  21696. +#endif /*_NETINET6_SHA1_H_*/
  21697. diff -Nur linux-2.6.29.1.orig/crypto/ocf/talitos/Makefile linux-2.6.29.1/crypto/ocf/talitos/Makefile
  21698. --- linux-2.6.29.1.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
  21699. +++ linux-2.6.29.1/crypto/ocf/talitos/Makefile 2009-04-20 20:01:21.632564980 +0200
  21700. @@ -0,0 +1,12 @@
  21701. +# for SGlinux builds
  21702. +-include $(ROOTDIR)/modules/.config
  21703. +
  21704. +obj-$(CONFIG_OCF_TALITOS) += talitos.o
  21705. +
  21706. +obj ?= .
  21707. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  21708. +
  21709. +ifdef TOPDIR
  21710. +-include $(TOPDIR)/Rules.make
  21711. +endif
  21712. +
  21713. diff -Nur linux-2.6.29.1.orig/crypto/ocf/talitos/talitos.c linux-2.6.29.1/crypto/ocf/talitos/talitos.c
  21714. --- linux-2.6.29.1.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
  21715. +++ linux-2.6.29.1/crypto/ocf/talitos/talitos.c 2009-04-20 20:01:21.632564980 +0200
  21716. @@ -0,0 +1,1359 @@
  21717. +/*
  21718. + * crypto/ocf/talitos/talitos.c
  21719. + *
  21720. + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
  21721. + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
  21722. + *
  21723. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  21724. + *
  21725. + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
  21726. + * some code copied from files with the following:
  21727. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com
  21728. + *
  21729. + * Redistribution and use in source and binary forms, with or without
  21730. + * modification, are permitted provided that the following conditions
  21731. + * are met:
  21732. + *
  21733. + * 1. Redistributions of source code must retain the above copyright
  21734. + * notice, this list of conditions and the following disclaimer.
  21735. + * 2. Redistributions in binary form must reproduce the above copyright
  21736. + * notice, this list of conditions and the following disclaimer in the
  21737. + * documentation and/or other materials provided with the distribution.
  21738. + * 3. The name of the author may not be used to endorse or promote products
  21739. + * derived from this software without specific prior written permission.
  21740. + *
  21741. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  21742. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21743. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  21744. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21745. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21746. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21747. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21748. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21749. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  21750. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21751. + *
  21752. + * ---------------------------------------------------------------------------
  21753. + *
  21754. + * NOTES:
  21755. + *
  21756. + * The Freescale SEC (also known as 'talitos') resides on the
  21757. + * internal bus, and runs asynchronous to the processor core. It has
  21758. + * a wide gamut of cryptographic acceleration features, including single-
  21759. + * pass IPsec (also known as algorithm chaining). To properly utilize
  21760. + * all of the SEC's performance enhancing features, further reworking
  21761. + * of higher level code (framework, applications) will be necessary.
  21762. + *
  21763. + * The following table shows which SEC version is present in which devices:
  21764. + *
  21765. + * Devices SEC version
  21766. + *
  21767. + * 8272, 8248 SEC 1.0
  21768. + * 885, 875 SEC 1.2
  21769. + * 8555E, 8541E SEC 2.0
  21770. + * 8349E SEC 2.01
  21771. + * 8548E SEC 2.1
  21772. + *
  21773. + * The following table shows the features offered by each SEC version:
  21774. + *
  21775. + * Max. chan-
  21776. + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
  21777. + *
  21778. + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
  21779. + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
  21780. + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
  21781. + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
  21782. + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
  21783. + *
  21784. + * Each execution unit in the SEC has two modes of execution; channel and
  21785. + * slave/debug. This driver employs the channel infrastructure in the
  21786. + * device for convenience. Only the RNG is directly accessed due to the
  21787. + * convenience of its random fifo pool. The relationship between the
  21788. + * channels and execution units is depicted in the following diagram:
  21789. + *
  21790. + * ------- ------------
  21791. + * ---| ch0 |---| |
  21792. + * ------- | |
  21793. + * | |------+-------+-------+-------+------------
  21794. + * ------- | | | | | | |
  21795. + * ---| ch1 |---| | | | | | |
  21796. + * ------- | | ------ ------ ------ ------ ------
  21797. + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
  21798. + * ------- | | ------ ------ ------ ------ ------
  21799. + * ---| ch2 |---| | | | | | |
  21800. + * ------- | | | | | | |
  21801. + * | |------+-------+-------+-------+------------
  21802. + * ------- | |
  21803. + * ---| ch3 |---| |
  21804. + * ------- ------------
  21805. + *
  21806. + * Channel ch0 may drive an aes operation to the aes unit (AESU),
  21807. + * and, at the same time, ch1 may drive a message digest operation
  21808. + * to the mdeu. Each channel has an input descriptor FIFO, and the
  21809. + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
  21810. + * a buffer overrun error is triggered. The controller is responsible
  21811. + * for fetching the data from descriptor pointers, and passing the
  21812. + * data to the appropriate EUs. The controller also writes the
  21813. + * cryptographic operation's result to memory. The SEC notifies
  21814. + * completion by triggering an interrupt and/or setting the 1st byte
  21815. + * of the hdr field to 0xff.
  21816. + *
  21817. + * TODO:
  21818. + * o support more algorithms
  21819. + * o support more versions of the SEC
  21820. + * o add support for linux 2.4
  21821. + * o scatter-gather (sg) support
  21822. + * o add support for public key ops (PKEU)
  21823. + * o add statistics
  21824. + */
  21825. +
  21826. +#ifndef AUTOCONF_INCLUDED
  21827. +#include <linux/config.h>
  21828. +#endif
  21829. +#include <linux/module.h>
  21830. +#include <linux/init.h>
  21831. +#include <linux/interrupt.h>
  21832. +#include <linux/spinlock.h>
  21833. +#include <linux/random.h>
  21834. +#include <linux/skbuff.h>
  21835. +#include <asm/scatterlist.h>
  21836. +#include <linux/dma-mapping.h> /* dma_map_single() */
  21837. +#include <linux/moduleparam.h>
  21838. +
  21839. +#include <linux/version.h>
  21840. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
  21841. +#include <linux/platform_device.h>
  21842. +#endif
  21843. +
  21844. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  21845. +#include <linux/of_platform.h>
  21846. +#endif
  21847. +
  21848. +#include <cryptodev.h>
  21849. +#include <uio.h>
  21850. +
  21851. +#define DRV_NAME "talitos"
  21852. +
  21853. +#include "talitos_dev.h"
  21854. +#include "talitos_soft.h"
  21855. +
  21856. +#define read_random(p,l) get_random_bytes(p,l)
  21857. +
  21858. +const char talitos_driver_name[] = "Talitos OCF";
  21859. +const char talitos_driver_version[] = "0.2";
  21860. +
  21861. +static int talitos_newsession(device_t dev, u_int32_t *sidp,
  21862. + struct cryptoini *cri);
  21863. +static int talitos_freesession(device_t dev, u_int64_t tid);
  21864. +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
  21865. +static void dump_talitos_status(struct talitos_softc *sc);
  21866. +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
  21867. + int chsel);
  21868. +static void talitos_doneprocessing(struct talitos_softc *sc);
  21869. +static void talitos_init_device(struct talitos_softc *sc);
  21870. +static void talitos_reset_device_master(struct talitos_softc *sc);
  21871. +static void talitos_reset_device(struct talitos_softc *sc);
  21872. +static void talitos_errorprocessing(struct talitos_softc *sc);
  21873. +#ifdef CONFIG_PPC_MERGE
  21874. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
  21875. +static int talitos_remove(struct of_device *ofdev);
  21876. +#else
  21877. +static int talitos_probe(struct platform_device *pdev);
  21878. +static int talitos_remove(struct platform_device *pdev);
  21879. +#endif
  21880. +#ifdef CONFIG_OCF_RANDOMHARVEST
  21881. +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
  21882. +static void talitos_rng_init(struct talitos_softc *sc);
  21883. +#endif
  21884. +
  21885. +static device_method_t talitos_methods = {
  21886. + /* crypto device methods */
  21887. + DEVMETHOD(cryptodev_newsession, talitos_newsession),
  21888. + DEVMETHOD(cryptodev_freesession,talitos_freesession),
  21889. + DEVMETHOD(cryptodev_process, talitos_process),
  21890. +};
  21891. +
  21892. +#define debug talitos_debug
  21893. +int talitos_debug = 0;
  21894. +module_param(talitos_debug, int, 0644);
  21895. +MODULE_PARM_DESC(talitos_debug, "Enable debug");
  21896. +
  21897. +static inline void talitos_write(volatile unsigned *addr, u32 val)
  21898. +{
  21899. + out_be32(addr, val);
  21900. +}
  21901. +
  21902. +static inline u32 talitos_read(volatile unsigned *addr)
  21903. +{
  21904. + u32 val;
  21905. + val = in_be32(addr);
  21906. + return val;
  21907. +}
  21908. +
  21909. +static void dump_talitos_status(struct talitos_softc *sc)
  21910. +{
  21911. + unsigned int v, v_hi, i, *ptr;
  21912. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  21913. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
  21914. + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
  21915. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  21916. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  21917. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  21918. + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
  21919. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  21920. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  21921. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  21922. + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
  21923. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  21924. + for (i = 0; i < sc->sc_num_channels; i++) {
  21925. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21926. + TALITOS_CH_CDPR);
  21927. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21928. + TALITOS_CH_CDPR_HI);
  21929. + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
  21930. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  21931. + }
  21932. + for (i = 0; i < sc->sc_num_channels; i++) {
  21933. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21934. + TALITOS_CH_CCPSR);
  21935. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  21936. + TALITOS_CH_CCPSR_HI);
  21937. + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
  21938. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  21939. + }
  21940. + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
  21941. + for (i = 0; i < 16; i++) {
  21942. + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
  21943. + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
  21944. + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
  21945. + }
  21946. + return;
  21947. +}
  21948. +
  21949. +
  21950. +#ifdef CONFIG_OCF_RANDOMHARVEST
  21951. +/*
  21952. + * pull random numbers off the RNG FIFO, not exceeding amount available
  21953. + */
  21954. +static int
  21955. +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
  21956. +{
  21957. + struct talitos_softc *sc = (struct talitos_softc *) arg;
  21958. + int rc;
  21959. + u_int32_t v;
  21960. +
  21961. + DPRINTF("%s()\n", __FUNCTION__);
  21962. +
  21963. + /* check for things like FIFO underflow */
  21964. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  21965. + if (unlikely(v)) {
  21966. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  21967. + device_get_nameunit(sc->sc_cdev), v);
  21968. + return 0;
  21969. + }
  21970. + /*
  21971. + * OFL is number of available 64-bit words,
  21972. + * shift and convert to a 32-bit word count
  21973. + */
  21974. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
  21975. + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
  21976. + if (maxwords > v)
  21977. + maxwords = v;
  21978. + for (rc = 0; rc < maxwords; rc++) {
  21979. + buf[rc] = talitos_read(sc->sc_base_addr +
  21980. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  21981. + }
  21982. + if (maxwords & 1) {
  21983. + /*
  21984. + * RNG will complain with an AE in the RNGISR
  21985. + * if we don't complete the pairs of 32-bit reads
  21986. + * to its 64-bit register based FIFO
  21987. + */
  21988. + v = talitos_read(sc->sc_base_addr +
  21989. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  21990. + }
  21991. +
  21992. + return rc;
  21993. +}
  21994. +
  21995. +static void
  21996. +talitos_rng_init(struct talitos_softc *sc)
  21997. +{
  21998. + u_int32_t v;
  21999. +
  22000. + DPRINTF("%s()\n", __FUNCTION__);
  22001. + /* reset RNG EU */
  22002. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
  22003. + v |= TALITOS_RNGRCR_HI_SR;
  22004. + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
  22005. + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
  22006. + & TALITOS_RNGSR_HI_RD) == 0)
  22007. + cpu_relax();
  22008. + /*
  22009. + * we tell the RNG to start filling the RNG FIFO
  22010. + * by writing the RNGDSR
  22011. + */
  22012. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
  22013. + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
  22014. + /*
  22015. + * 64 bits of data will be pushed onto the FIFO every
  22016. + * 256 SEC cycles until the FIFO is full. The RNG then
  22017. + * attempts to keep the FIFO full.
  22018. + */
  22019. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  22020. + if (v) {
  22021. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  22022. + device_get_nameunit(sc->sc_cdev), v);
  22023. + return;
  22024. + }
  22025. + /*
  22026. + * n.b. we need to add a FIPS test here - if the RNG is going
  22027. + * to fail, it's going to fail at reset time
  22028. + */
  22029. + return;
  22030. +}
  22031. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  22032. +
  22033. +/*
  22034. + * Generate a new software session.
  22035. + */
  22036. +static int
  22037. +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  22038. +{
  22039. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  22040. + struct talitos_softc *sc = device_get_softc(dev);
  22041. + struct talitos_session *ses = NULL;
  22042. + int sesn;
  22043. +
  22044. + DPRINTF("%s()\n", __FUNCTION__);
  22045. + if (sidp == NULL || cri == NULL || sc == NULL) {
  22046. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  22047. + return EINVAL;
  22048. + }
  22049. + for (c = cri; c != NULL; c = c->cri_next) {
  22050. + if (c->cri_alg == CRYPTO_MD5 ||
  22051. + c->cri_alg == CRYPTO_MD5_HMAC ||
  22052. + c->cri_alg == CRYPTO_SHA1 ||
  22053. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  22054. + c->cri_alg == CRYPTO_NULL_HMAC) {
  22055. + if (macini)
  22056. + return EINVAL;
  22057. + macini = c;
  22058. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  22059. + c->cri_alg == CRYPTO_3DES_CBC ||
  22060. + c->cri_alg == CRYPTO_AES_CBC ||
  22061. + c->cri_alg == CRYPTO_NULL_CBC) {
  22062. + if (encini)
  22063. + return EINVAL;
  22064. + encini = c;
  22065. + } else {
  22066. + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
  22067. + return EINVAL;
  22068. + }
  22069. + }
  22070. + if (encini == NULL && macini == NULL)
  22071. + return EINVAL;
  22072. + if (encini) {
  22073. + /* validate key length */
  22074. + switch (encini->cri_alg) {
  22075. + case CRYPTO_DES_CBC:
  22076. + if (encini->cri_klen != 64)
  22077. + return EINVAL;
  22078. + break;
  22079. + case CRYPTO_3DES_CBC:
  22080. + if (encini->cri_klen != 192) {
  22081. + return EINVAL;
  22082. + }
  22083. + break;
  22084. + case CRYPTO_AES_CBC:
  22085. + if (encini->cri_klen != 128 &&
  22086. + encini->cri_klen != 192 &&
  22087. + encini->cri_klen != 256)
  22088. + return EINVAL;
  22089. + break;
  22090. + default:
  22091. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  22092. + encini->cri_alg);
  22093. + return EINVAL;
  22094. + }
  22095. + }
  22096. +
  22097. + if (sc->sc_sessions == NULL) {
  22098. + ses = sc->sc_sessions = (struct talitos_session *)
  22099. + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
  22100. + if (ses == NULL)
  22101. + return ENOMEM;
  22102. + memset(ses, 0, sizeof(struct talitos_session));
  22103. + sesn = 0;
  22104. + sc->sc_nsessions = 1;
  22105. + } else {
  22106. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  22107. + if (sc->sc_sessions[sesn].ses_used == 0) {
  22108. + ses = &sc->sc_sessions[sesn];
  22109. + break;
  22110. + }
  22111. + }
  22112. +
  22113. + if (ses == NULL) {
  22114. + /* allocating session */
  22115. + sesn = sc->sc_nsessions;
  22116. + ses = (struct talitos_session *) kmalloc(
  22117. + (sesn + 1) * sizeof(struct talitos_session),
  22118. + SLAB_ATOMIC);
  22119. + if (ses == NULL)
  22120. + return ENOMEM;
  22121. + memset(ses, 0,
  22122. + (sesn + 1) * sizeof(struct talitos_session));
  22123. + memcpy(ses, sc->sc_sessions,
  22124. + sesn * sizeof(struct talitos_session));
  22125. + memset(sc->sc_sessions, 0,
  22126. + sesn * sizeof(struct talitos_session));
  22127. + kfree(sc->sc_sessions);
  22128. + sc->sc_sessions = ses;
  22129. + ses = &sc->sc_sessions[sesn];
  22130. + sc->sc_nsessions++;
  22131. + }
  22132. + }
  22133. +
  22134. + ses->ses_used = 1;
  22135. +
  22136. + if (encini) {
  22137. + /* get an IV */
  22138. + /* XXX may read fewer than requested */
  22139. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  22140. +
  22141. + ses->ses_klen = (encini->cri_klen + 7) / 8;
  22142. + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
  22143. + if (macini) {
  22144. + /* doing hash on top of cipher */
  22145. + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
  22146. + memcpy(ses->ses_hmac, macini->cri_key,
  22147. + ses->ses_hmac_len);
  22148. + }
  22149. + } else if (macini) {
  22150. + /* doing hash */
  22151. + ses->ses_klen = (macini->cri_klen + 7) / 8;
  22152. + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
  22153. + }
  22154. +
  22155. + /* back compat way of determining MSC result len */
  22156. + if (macini) {
  22157. + ses->ses_mlen = macini->cri_mlen;
  22158. + if (ses->ses_mlen == 0) {
  22159. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  22160. + ses->ses_mlen = MD5_HASH_LEN;
  22161. + else
  22162. + ses->ses_mlen = SHA1_HASH_LEN;
  22163. + }
  22164. + }
  22165. +
  22166. + /* really should make up a template td here,
  22167. + * and only fill things like i/o and direction in process() */
  22168. +
  22169. + /* assign session ID */
  22170. + *sidp = TALITOS_SID(sc->sc_num, sesn);
  22171. + return 0;
  22172. +}
  22173. +
  22174. +/*
  22175. + * Deallocate a session.
  22176. + */
  22177. +static int
  22178. +talitos_freesession(device_t dev, u_int64_t tid)
  22179. +{
  22180. + struct talitos_softc *sc = device_get_softc(dev);
  22181. + int session, ret;
  22182. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  22183. +
  22184. + if (sc == NULL)
  22185. + return EINVAL;
  22186. + session = TALITOS_SESSION(sid);
  22187. + if (session < sc->sc_nsessions) {
  22188. + memset(&sc->sc_sessions[session], 0,
  22189. + sizeof(sc->sc_sessions[session]));
  22190. + ret = 0;
  22191. + } else
  22192. + ret = EINVAL;
  22193. + return ret;
  22194. +}
  22195. +
  22196. +/*
  22197. + * launch device processing - it will come back with done notification
  22198. + * in the form of an interrupt and/or HDR_DONE_BITS in header
  22199. + */
  22200. +static int
  22201. +talitos_submit(
  22202. + struct talitos_softc *sc,
  22203. + struct talitos_desc *td,
  22204. + int chsel)
  22205. +{
  22206. + u_int32_t v;
  22207. +
  22208. + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
  22209. + talitos_write(sc->sc_base_addr +
  22210. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
  22211. + talitos_write(sc->sc_base_addr +
  22212. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
  22213. + return 0;
  22214. +}
  22215. +
  22216. +static int
  22217. +talitos_process(device_t dev, struct cryptop *crp, int hint)
  22218. +{
  22219. + int i, err = 0, ivsize;
  22220. + struct talitos_softc *sc = device_get_softc(dev);
  22221. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  22222. + caddr_t iv;
  22223. + struct talitos_session *ses;
  22224. + struct talitos_desc *td;
  22225. + unsigned long flags;
  22226. + /* descriptor mappings */
  22227. + int hmac_key, hmac_data, cipher_iv, cipher_key,
  22228. + in_fifo, out_fifo, cipher_iv_out;
  22229. + static int chsel = -1;
  22230. +
  22231. + DPRINTF("%s()\n", __FUNCTION__);
  22232. +
  22233. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  22234. + return EINVAL;
  22235. + }
  22236. + crp->crp_etype = 0;
  22237. + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  22238. + return EINVAL;
  22239. + }
  22240. +
  22241. + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
  22242. +
  22243. + /* enter the channel scheduler */
  22244. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22245. +
  22246. + /* reuse channel that already had/has requests for the required EU */
  22247. + for (i = 0; i < sc->sc_num_channels; i++) {
  22248. + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
  22249. + break;
  22250. + }
  22251. + if (i == sc->sc_num_channels) {
  22252. + /*
  22253. + * haven't seen this algo the last sc_num_channels or more
  22254. + * use round robin in this case
  22255. + * nb: sc->sc_num_channels must be power of 2
  22256. + */
  22257. + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
  22258. + } else {
  22259. + /*
  22260. + * matches channel with same target execution unit;
  22261. + * use same channel in this case
  22262. + */
  22263. + chsel = i;
  22264. + }
  22265. + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
  22266. +
  22267. + /* release the channel scheduler lock */
  22268. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22269. +
  22270. + /* acquire the selected channel fifo lock */
  22271. + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
  22272. +
  22273. + /* find and reserve next available descriptor-cryptop pair */
  22274. + for (i = 0; i < sc->sc_chfifo_len; i++) {
  22275. + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
  22276. + /*
  22277. + * ensure correct descriptor formation by
  22278. + * avoiding inadvertently setting "optional" entries
  22279. + * e.g. not using "optional" dptr2 for MD/HMAC descs
  22280. + */
  22281. + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
  22282. + 0, sizeof(*td));
  22283. + /* reserve it with done notification request bit */
  22284. + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
  22285. + TALITOS_DONE_NOTIFY;
  22286. + break;
  22287. + }
  22288. + }
  22289. + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
  22290. +
  22291. + if (i == sc->sc_chfifo_len) {
  22292. + /* fifo full */
  22293. + err = ERESTART;
  22294. + goto errout;
  22295. + }
  22296. +
  22297. + td = &sc->sc_chnfifo[chsel][i].cf_desc;
  22298. + sc->sc_chnfifo[chsel][i].cf_crp = crp;
  22299. +
  22300. + crd1 = crp->crp_desc;
  22301. + if (crd1 == NULL) {
  22302. + err = EINVAL;
  22303. + goto errout;
  22304. + }
  22305. + crd2 = crd1->crd_next;
  22306. + /* prevent compiler warning */
  22307. + hmac_key = 0;
  22308. + hmac_data = 0;
  22309. + if (crd2 == NULL) {
  22310. + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
  22311. + /* assign descriptor dword ptr mappings for this desc. type */
  22312. + cipher_iv = 1;
  22313. + cipher_key = 2;
  22314. + in_fifo = 3;
  22315. + cipher_iv_out = 5;
  22316. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  22317. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  22318. + crd1->crd_alg == CRYPTO_SHA1 ||
  22319. + crd1->crd_alg == CRYPTO_MD5) {
  22320. + out_fifo = 5;
  22321. + maccrd = crd1;
  22322. + enccrd = NULL;
  22323. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  22324. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  22325. + crd1->crd_alg == CRYPTO_AES_CBC ||
  22326. + crd1->crd_alg == CRYPTO_ARC4) {
  22327. + out_fifo = 4;
  22328. + maccrd = NULL;
  22329. + enccrd = crd1;
  22330. + } else {
  22331. + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
  22332. + err = EINVAL;
  22333. + goto errout;
  22334. + }
  22335. + } else {
  22336. + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
  22337. + td->hdr |= TD_TYPE_IPSEC_ESP;
  22338. + } else {
  22339. + DPRINTF("unimplemented: multiple descriptor ipsec\n");
  22340. + err = EINVAL;
  22341. + goto errout;
  22342. + }
  22343. + /* assign descriptor dword ptr mappings for this desc. type */
  22344. + hmac_key = 0;
  22345. + hmac_data = 1;
  22346. + cipher_iv = 2;
  22347. + cipher_key = 3;
  22348. + in_fifo = 4;
  22349. + out_fifo = 5;
  22350. + cipher_iv_out = 6;
  22351. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  22352. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  22353. + crd1->crd_alg == CRYPTO_MD5 ||
  22354. + crd1->crd_alg == CRYPTO_SHA1) &&
  22355. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  22356. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  22357. + crd2->crd_alg == CRYPTO_AES_CBC ||
  22358. + crd2->crd_alg == CRYPTO_ARC4) &&
  22359. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  22360. + maccrd = crd1;
  22361. + enccrd = crd2;
  22362. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  22363. + crd1->crd_alg == CRYPTO_ARC4 ||
  22364. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  22365. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  22366. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  22367. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  22368. + crd2->crd_alg == CRYPTO_MD5 ||
  22369. + crd2->crd_alg == CRYPTO_SHA1) &&
  22370. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  22371. + enccrd = crd1;
  22372. + maccrd = crd2;
  22373. + } else {
  22374. + /* We cannot order the SEC as requested */
  22375. + printk("%s: cannot do the order\n",
  22376. + device_get_nameunit(sc->sc_cdev));
  22377. + err = EINVAL;
  22378. + goto errout;
  22379. + }
  22380. + }
  22381. + /* assign in_fifo and out_fifo based on input/output struct type */
  22382. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  22383. + /* using SKB buffers */
  22384. + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
  22385. + if (skb_shinfo(skb)->nr_frags) {
  22386. + printk("%s: skb frags unimplemented\n",
  22387. + device_get_nameunit(sc->sc_cdev));
  22388. + err = EINVAL;
  22389. + goto errout;
  22390. + }
  22391. + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
  22392. + skb->len, DMA_TO_DEVICE);
  22393. + td->ptr[in_fifo].len = skb->len;
  22394. + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
  22395. + skb->len, DMA_TO_DEVICE);
  22396. + td->ptr[out_fifo].len = skb->len;
  22397. + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
  22398. + skb->len, DMA_TO_DEVICE);
  22399. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  22400. + /* using IOV buffers */
  22401. + struct uio *uiop = (struct uio *)crp->crp_buf;
  22402. + if (uiop->uio_iovcnt > 1) {
  22403. + printk("%s: iov frags unimplemented\n",
  22404. + device_get_nameunit(sc->sc_cdev));
  22405. + err = EINVAL;
  22406. + goto errout;
  22407. + }
  22408. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  22409. + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
  22410. + td->ptr[in_fifo].len = crp->crp_ilen;
  22411. + /* crp_olen is never set; always use crp_ilen */
  22412. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  22413. + uiop->uio_iov->iov_base,
  22414. + crp->crp_ilen, DMA_TO_DEVICE);
  22415. + td->ptr[out_fifo].len = crp->crp_ilen;
  22416. + } else {
  22417. + /* using contig buffers */
  22418. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  22419. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  22420. + td->ptr[in_fifo].len = crp->crp_ilen;
  22421. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  22422. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  22423. + td->ptr[out_fifo].len = crp->crp_ilen;
  22424. + }
  22425. + if (enccrd) {
  22426. + switch (enccrd->crd_alg) {
  22427. + case CRYPTO_3DES_CBC:
  22428. + td->hdr |= TALITOS_MODE0_DEU_3DES;
  22429. + /* FALLTHROUGH */
  22430. + case CRYPTO_DES_CBC:
  22431. + td->hdr |= TALITOS_SEL0_DEU
  22432. + | TALITOS_MODE0_DEU_CBC;
  22433. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  22434. + td->hdr |= TALITOS_MODE0_DEU_ENC;
  22435. + ivsize = 2*sizeof(u_int32_t);
  22436. + DPRINTF("%cDES ses %d ch %d len %d\n",
  22437. + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
  22438. + (u32)TALITOS_SESSION(crp->crp_sid),
  22439. + chsel, td->ptr[in_fifo].len);
  22440. + break;
  22441. + case CRYPTO_AES_CBC:
  22442. + td->hdr |= TALITOS_SEL0_AESU
  22443. + | TALITOS_MODE0_AESU_CBC;
  22444. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  22445. + td->hdr |= TALITOS_MODE0_AESU_ENC;
  22446. + ivsize = 4*sizeof(u_int32_t);
  22447. + DPRINTF("AES ses %d ch %d len %d\n",
  22448. + (u32)TALITOS_SESSION(crp->crp_sid),
  22449. + chsel, td->ptr[in_fifo].len);
  22450. + break;
  22451. + default:
  22452. + printk("%s: unimplemented enccrd->crd_alg %d\n",
  22453. + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
  22454. + err = EINVAL;
  22455. + goto errout;
  22456. + }
  22457. + /*
  22458. + * Setup encrypt/decrypt state. When using basic ops
  22459. + * we can't use an inline IV because hash/crypt offset
  22460. + * must be from the end of the IV to the start of the
  22461. + * crypt data and this leaves out the preceding header
  22462. + * from the hash calculation. Instead we place the IV
  22463. + * in the state record and set the hash/crypt offset to
  22464. + * copy both the header+IV.
  22465. + */
  22466. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  22467. + td->hdr |= TALITOS_DIR_OUTBOUND;
  22468. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  22469. + iv = enccrd->crd_iv;
  22470. + else
  22471. + iv = (caddr_t) ses->ses_iv;
  22472. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  22473. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  22474. + enccrd->crd_inject, ivsize, iv);
  22475. + }
  22476. + } else {
  22477. + td->hdr |= TALITOS_DIR_INBOUND;
  22478. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  22479. + iv = enccrd->crd_iv;
  22480. + bcopy(enccrd->crd_iv, iv, ivsize);
  22481. + } else {
  22482. + iv = (caddr_t) ses->ses_iv;
  22483. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  22484. + enccrd->crd_inject, ivsize, iv);
  22485. + }
  22486. + }
  22487. + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
  22488. + DMA_TO_DEVICE);
  22489. + td->ptr[cipher_iv].len = ivsize;
  22490. + /*
  22491. + * we don't need the cipher iv out length/pointer
  22492. + * field to do ESP IPsec. Therefore we set the len field as 0,
  22493. + * which tells the SEC not to do anything with this len/ptr
  22494. + * field. Previously, when length/pointer as pointing to iv,
  22495. + * it gave us corruption of packets.
  22496. + */
  22497. + td->ptr[cipher_iv_out].len = 0;
  22498. + }
  22499. + if (enccrd && maccrd) {
  22500. + /* this is ipsec only for now */
  22501. + td->hdr |= TALITOS_SEL1_MDEU
  22502. + | TALITOS_MODE1_MDEU_INIT
  22503. + | TALITOS_MODE1_MDEU_PAD;
  22504. + switch (maccrd->crd_alg) {
  22505. + case CRYPTO_MD5:
  22506. + td->hdr |= TALITOS_MODE1_MDEU_MD5;
  22507. + break;
  22508. + case CRYPTO_MD5_HMAC:
  22509. + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
  22510. + break;
  22511. + case CRYPTO_SHA1:
  22512. + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
  22513. + break;
  22514. + case CRYPTO_SHA1_HMAC:
  22515. + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
  22516. + break;
  22517. + default:
  22518. + /* We cannot order the SEC as requested */
  22519. + printk("%s: cannot do the order\n",
  22520. + device_get_nameunit(sc->sc_cdev));
  22521. + err = EINVAL;
  22522. + goto errout;
  22523. + }
  22524. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  22525. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  22526. + /*
  22527. + * The offset from hash data to the start of
  22528. + * crypt data is the difference in the skips.
  22529. + */
  22530. + /* ipsec only for now */
  22531. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  22532. + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
  22533. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  22534. + td->ptr[in_fifo].ptr += enccrd->crd_skip;
  22535. + td->ptr[in_fifo].len = enccrd->crd_len;
  22536. + td->ptr[out_fifo].ptr += enccrd->crd_skip;
  22537. + td->ptr[out_fifo].len = enccrd->crd_len;
  22538. + /* bytes of HMAC to postpend to ciphertext */
  22539. + td->ptr[out_fifo].extent = ses->ses_mlen;
  22540. + td->ptr[hmac_data].ptr += maccrd->crd_skip;
  22541. + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
  22542. + }
  22543. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  22544. + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
  22545. + device_get_nameunit(sc->sc_cdev));
  22546. + }
  22547. + }
  22548. + if (!enccrd && maccrd) {
  22549. + /* single MD5 or SHA */
  22550. + td->hdr |= TALITOS_SEL0_MDEU
  22551. + | TALITOS_MODE0_MDEU_INIT
  22552. + | TALITOS_MODE0_MDEU_PAD;
  22553. + switch (maccrd->crd_alg) {
  22554. + case CRYPTO_MD5:
  22555. + td->hdr |= TALITOS_MODE0_MDEU_MD5;
  22556. + DPRINTF("MD5 ses %d ch %d len %d\n",
  22557. + (u32)TALITOS_SESSION(crp->crp_sid),
  22558. + chsel, td->ptr[in_fifo].len);
  22559. + break;
  22560. + case CRYPTO_MD5_HMAC:
  22561. + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
  22562. + break;
  22563. + case CRYPTO_SHA1:
  22564. + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
  22565. + DPRINTF("SHA1 ses %d ch %d len %d\n",
  22566. + (u32)TALITOS_SESSION(crp->crp_sid),
  22567. + chsel, td->ptr[in_fifo].len);
  22568. + break;
  22569. + case CRYPTO_SHA1_HMAC:
  22570. + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
  22571. + break;
  22572. + default:
  22573. + /* We cannot order the SEC as requested */
  22574. + DPRINTF("cannot do the order\n");
  22575. + err = EINVAL;
  22576. + goto errout;
  22577. + }
  22578. +
  22579. + if (crp->crp_flags & CRYPTO_F_IOV)
  22580. + td->ptr[out_fifo].ptr += maccrd->crd_inject;
  22581. +
  22582. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  22583. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  22584. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  22585. + ses->ses_hmac, ses->ses_hmac_len,
  22586. + DMA_TO_DEVICE);
  22587. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  22588. + }
  22589. + }
  22590. + else {
  22591. + /* using process key (session data has duplicate) */
  22592. + td->ptr[cipher_key].ptr = dma_map_single(NULL,
  22593. + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
  22594. + DMA_TO_DEVICE);
  22595. + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
  22596. + }
  22597. + /* descriptor complete - GO! */
  22598. + return talitos_submit(sc, td, chsel);
  22599. +
  22600. +errout:
  22601. + if (err != ERESTART) {
  22602. + crp->crp_etype = err;
  22603. + crypto_done(crp);
  22604. + }
  22605. + return err;
  22606. +}
  22607. +
  22608. +/* go through all channels descriptors, notifying OCF what has
  22609. + * _and_hasn't_ successfully completed and reset the device
  22610. + * (otherwise it's up to decoding desc hdrs!)
  22611. + */
  22612. +static void talitos_errorprocessing(struct talitos_softc *sc)
  22613. +{
  22614. + unsigned long flags;
  22615. + int i, j;
  22616. +
  22617. + /* disable further scheduling until under control */
  22618. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22619. +
  22620. + if (debug) dump_talitos_status(sc);
  22621. + /* go through descriptors, try and salvage those successfully done,
  22622. + * and EIO those that weren't
  22623. + */
  22624. + for (i = 0; i < sc->sc_num_channels; i++) {
  22625. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  22626. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  22627. + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
  22628. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  22629. + & TALITOS_HDR_DONE_BITS)
  22630. + != TALITOS_HDR_DONE_BITS) {
  22631. + /* this one didn't finish */
  22632. + /* signify in crp->etype */
  22633. + sc->sc_chnfifo[i][j].cf_crp->crp_etype
  22634. + = EIO;
  22635. + }
  22636. + } else
  22637. + continue; /* free entry */
  22638. + /* either way, notify ocf */
  22639. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  22640. + /* and tag it available again
  22641. + *
  22642. + * memset to ensure correct descriptor formation by
  22643. + * avoiding inadvertently setting "optional" entries
  22644. + * e.g. not using "optional" dptr2 MD/HMAC processing
  22645. + */
  22646. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  22647. + 0, sizeof(struct talitos_desc));
  22648. + }
  22649. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  22650. + }
  22651. + /* reset and initialize the SEC h/w device */
  22652. + talitos_reset_device(sc);
  22653. + talitos_init_device(sc);
  22654. +#ifdef CONFIG_OCF_RANDOMHARVEST
  22655. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
  22656. + talitos_rng_init(sc);
  22657. +#endif
  22658. +
  22659. + /* Okay. Stand by. */
  22660. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  22661. +
  22662. + return;
  22663. +}
  22664. +
  22665. +/* go through all channels descriptors, notifying OCF what's been done */
  22666. +static void talitos_doneprocessing(struct talitos_softc *sc)
  22667. +{
  22668. + unsigned long flags;
  22669. + int i, j;
  22670. +
  22671. + /* go through descriptors looking for done bits */
  22672. + for (i = 0; i < sc->sc_num_channels; i++) {
  22673. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  22674. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  22675. + /* descriptor has done bits set? */
  22676. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  22677. + & TALITOS_HDR_DONE_BITS)
  22678. + == TALITOS_HDR_DONE_BITS) {
  22679. + /* notify ocf */
  22680. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  22681. + /* and tag it available again
  22682. + *
  22683. + * memset to ensure correct descriptor formation by
  22684. + * avoiding inadvertently setting "optional" entries
  22685. + * e.g. not using "optional" dptr2 MD/HMAC processing
  22686. + */
  22687. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  22688. + 0, sizeof(struct talitos_desc));
  22689. + }
  22690. + }
  22691. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  22692. + }
  22693. + return;
  22694. +}
  22695. +
  22696. +static irqreturn_t
  22697. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  22698. +talitos_intr(int irq, void *arg)
  22699. +#else
  22700. +talitos_intr(int irq, void *arg, struct pt_regs *regs)
  22701. +#endif
  22702. +{
  22703. + struct talitos_softc *sc = arg;
  22704. + u_int32_t v, v_hi;
  22705. +
  22706. + /* ack */
  22707. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  22708. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  22709. + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
  22710. + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
  22711. +
  22712. + if (unlikely(v & TALITOS_ISR_ERROR)) {
  22713. + /* Okay, Houston, we've had a problem here. */
  22714. + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
  22715. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  22716. + talitos_errorprocessing(sc);
  22717. + } else
  22718. + if (likely(v & TALITOS_ISR_DONE)) {
  22719. + talitos_doneprocessing(sc);
  22720. + }
  22721. + return IRQ_HANDLED;
  22722. +}
  22723. +
  22724. +/*
  22725. + * Initialize registers we need to touch only once.
  22726. + */
  22727. +static void
  22728. +talitos_init_device(struct talitos_softc *sc)
  22729. +{
  22730. + u_int32_t v;
  22731. + int i;
  22732. +
  22733. + DPRINTF("%s()\n", __FUNCTION__);
  22734. +
  22735. + /* init all channels */
  22736. + for (i = 0; i < sc->sc_num_channels; i++) {
  22737. + v = talitos_read(sc->sc_base_addr +
  22738. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
  22739. + v |= TALITOS_CH_CCCR_HI_CDWE
  22740. + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
  22741. + talitos_write(sc->sc_base_addr +
  22742. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
  22743. + }
  22744. + /* enable all interrupts */
  22745. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  22746. + v |= TALITOS_IMR_ALL;
  22747. + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
  22748. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  22749. + v |= TALITOS_IMR_HI_ERRONLY;
  22750. + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
  22751. + return;
  22752. +}
  22753. +
  22754. +/*
  22755. + * set the master reset bit on the device.
  22756. + */
  22757. +static void
  22758. +talitos_reset_device_master(struct talitos_softc *sc)
  22759. +{
  22760. + u_int32_t v;
  22761. +
  22762. + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
  22763. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  22764. + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
  22765. +
  22766. + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
  22767. + cpu_relax();
  22768. +
  22769. + return;
  22770. +}
  22771. +
  22772. +/*
  22773. + * Resets the device. Values in the registers are left as is
  22774. + * from the reset (i.e. initial values are assigned elsewhere).
  22775. + */
  22776. +static void
  22777. +talitos_reset_device(struct talitos_softc *sc)
  22778. +{
  22779. + u_int32_t v;
  22780. + int i;
  22781. +
  22782. + DPRINTF("%s()\n", __FUNCTION__);
  22783. +
  22784. + /*
  22785. + * Master reset
  22786. + * errata documentation: warning: certain SEC interrupts
  22787. + * are not fully cleared by writing the MCR:SWR bit,
  22788. + * set bit twice to completely reset
  22789. + */
  22790. + talitos_reset_device_master(sc); /* once */
  22791. + talitos_reset_device_master(sc); /* and once again */
  22792. +
  22793. + /* reset all channels */
  22794. + for (i = 0; i < sc->sc_num_channels; i++) {
  22795. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  22796. + TALITOS_CH_CCCR);
  22797. + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  22798. + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
  22799. + }
  22800. +}
  22801. +
  22802. +/* Set up the crypto device structure, private data,
  22803. + * and anything else we need before we start */
  22804. +#ifdef CONFIG_PPC_MERGE
  22805. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
  22806. +#else
  22807. +static int talitos_probe(struct platform_device *pdev)
  22808. +#endif
  22809. +{
  22810. + struct talitos_softc *sc = NULL;
  22811. + struct resource *r;
  22812. +#ifdef CONFIG_PPC_MERGE
  22813. + struct device *device = &ofdev->dev;
  22814. + struct device_node *np = ofdev->node;
  22815. + const unsigned int *prop;
  22816. + int err;
  22817. + struct resource res;
  22818. +#endif
  22819. + static int num_chips = 0;
  22820. + int rc;
  22821. + int i;
  22822. +
  22823. + DPRINTF("%s()\n", __FUNCTION__);
  22824. +
  22825. + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  22826. + if (!sc)
  22827. + return -ENOMEM;
  22828. + memset(sc, 0, sizeof(*sc));
  22829. +
  22830. + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
  22831. +
  22832. + sc->sc_irq = -1;
  22833. + sc->sc_cid = -1;
  22834. +#ifndef CONFIG_PPC_MERGE
  22835. + sc->sc_dev = pdev;
  22836. +#endif
  22837. + sc->sc_num = num_chips++;
  22838. +
  22839. +#ifdef CONFIG_PPC_MERGE
  22840. + dev_set_drvdata(device, sc);
  22841. +#else
  22842. + platform_set_drvdata(sc->sc_dev, sc);
  22843. +#endif
  22844. +
  22845. + /* get the irq line */
  22846. +#ifdef CONFIG_PPC_MERGE
  22847. + err = of_address_to_resource(np, 0, &res);
  22848. + if (err)
  22849. + return -EINVAL;
  22850. + r = &res;
  22851. +
  22852. + sc->sc_irq = irq_of_parse_and_map(np, 0);
  22853. +#else
  22854. + /* get a pointer to the register memory */
  22855. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  22856. +
  22857. + sc->sc_irq = platform_get_irq(pdev, 0);
  22858. +#endif
  22859. + rc = request_irq(sc->sc_irq, talitos_intr, 0,
  22860. + device_get_nameunit(sc->sc_cdev), sc);
  22861. + if (rc) {
  22862. + printk(KERN_ERR "%s: failed to hook irq %d\n",
  22863. + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
  22864. + sc->sc_irq = -1;
  22865. + goto out;
  22866. + }
  22867. +
  22868. + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
  22869. + if (!sc->sc_base_addr) {
  22870. + printk(KERN_ERR "%s: failed to ioremap\n",
  22871. + device_get_nameunit(sc->sc_cdev));
  22872. + goto out;
  22873. + }
  22874. +
  22875. + /* figure out our SEC's properties and capabilities */
  22876. + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
  22877. + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
  22878. + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
  22879. +
  22880. +#ifdef CONFIG_PPC_MERGE
  22881. + /* get SEC properties from device tree, defaulting to SEC 2.0 */
  22882. +
  22883. + prop = of_get_property(np, "num-channels", NULL);
  22884. + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
  22885. +
  22886. + prop = of_get_property(np, "channel-fifo-len", NULL);
  22887. + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
  22888. +
  22889. + prop = of_get_property(np, "exec-units-mask", NULL);
  22890. + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
  22891. +
  22892. + prop = of_get_property(np, "descriptor-types-mask", NULL);
  22893. + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
  22894. +#else
  22895. + /* bulk should go away with openfirmware flat device tree support */
  22896. + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
  22897. + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
  22898. + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
  22899. + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
  22900. + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
  22901. + } else {
  22902. + printk(KERN_ERR "%s: failed to id device\n",
  22903. + device_get_nameunit(sc->sc_cdev));
  22904. + goto out;
  22905. + }
  22906. +#endif
  22907. +
  22908. + /* + 1 is for the meta-channel lock used by the channel scheduler */
  22909. + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
  22910. + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
  22911. + if (!sc->sc_chnfifolock)
  22912. + goto out;
  22913. + for (i = 0; i < sc->sc_num_channels + 1; i++) {
  22914. + spin_lock_init(&sc->sc_chnfifolock[i]);
  22915. + }
  22916. +
  22917. + sc->sc_chnlastalg = (int *) kmalloc(
  22918. + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
  22919. + if (!sc->sc_chnlastalg)
  22920. + goto out;
  22921. + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
  22922. +
  22923. + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
  22924. + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
  22925. + GFP_KERNEL);
  22926. + if (!sc->sc_chnfifo)
  22927. + goto out;
  22928. + for (i = 0; i < sc->sc_num_channels; i++) {
  22929. + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
  22930. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
  22931. + GFP_KERNEL);
  22932. + if (!sc->sc_chnfifo[i])
  22933. + goto out;
  22934. + memset(sc->sc_chnfifo[i], 0,
  22935. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
  22936. + }
  22937. +
  22938. + /* reset and initialize the SEC h/w device */
  22939. + talitos_reset_device(sc);
  22940. + talitos_init_device(sc);
  22941. +
  22942. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  22943. + if (sc->sc_cid < 0) {
  22944. + printk(KERN_ERR "%s: could not get crypto driver id\n",
  22945. + device_get_nameunit(sc->sc_cdev));
  22946. + goto out;
  22947. + }
  22948. +
  22949. + /* register algorithms with the framework */
  22950. + printk("%s:", device_get_nameunit(sc->sc_cdev));
  22951. +
  22952. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
  22953. + printk(" rng");
  22954. +#ifdef CONFIG_OCF_RANDOMHARVEST
  22955. + talitos_rng_init(sc);
  22956. + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
  22957. +#endif
  22958. + }
  22959. + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
  22960. + printk(" des/3des");
  22961. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  22962. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  22963. + }
  22964. + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
  22965. + printk(" aes");
  22966. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  22967. + }
  22968. + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
  22969. + printk(" md5");
  22970. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  22971. + /* HMAC support only with IPsec for now */
  22972. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  22973. + printk(" sha1");
  22974. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  22975. + /* HMAC support only with IPsec for now */
  22976. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  22977. + }
  22978. + printk("\n");
  22979. + return 0;
  22980. +
  22981. +out:
  22982. +#ifndef CONFIG_PPC_MERGE
  22983. + talitos_remove(pdev);
  22984. +#endif
  22985. + return -ENOMEM;
  22986. +}
  22987. +
  22988. +#ifdef CONFIG_PPC_MERGE
  22989. +static int talitos_remove(struct of_device *ofdev)
  22990. +#else
  22991. +static int talitos_remove(struct platform_device *pdev)
  22992. +#endif
  22993. +{
  22994. +#ifdef CONFIG_PPC_MERGE
  22995. + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
  22996. +#else
  22997. + struct talitos_softc *sc = platform_get_drvdata(pdev);
  22998. +#endif
  22999. + int i;
  23000. +
  23001. + DPRINTF("%s()\n", __FUNCTION__);
  23002. + if (sc->sc_cid >= 0)
  23003. + crypto_unregister_all(sc->sc_cid);
  23004. + if (sc->sc_chnfifo) {
  23005. + for (i = 0; i < sc->sc_num_channels; i++)
  23006. + if (sc->sc_chnfifo[i])
  23007. + kfree(sc->sc_chnfifo[i]);
  23008. + kfree(sc->sc_chnfifo);
  23009. + }
  23010. + if (sc->sc_chnlastalg)
  23011. + kfree(sc->sc_chnlastalg);
  23012. + if (sc->sc_chnfifolock)
  23013. + kfree(sc->sc_chnfifolock);
  23014. + if (sc->sc_irq != -1)
  23015. + free_irq(sc->sc_irq, sc);
  23016. + if (sc->sc_base_addr)
  23017. + iounmap((void *) sc->sc_base_addr);
  23018. + kfree(sc);
  23019. + return 0;
  23020. +}
  23021. +
  23022. +#ifdef CONFIG_PPC_MERGE
  23023. +static struct of_device_id talitos_match[] = {
  23024. + {
  23025. + .type = "crypto",
  23026. + .compatible = "talitos",
  23027. + },
  23028. + {},
  23029. +};
  23030. +
  23031. +MODULE_DEVICE_TABLE(of, talitos_match);
  23032. +
  23033. +static struct of_platform_driver talitos_driver = {
  23034. + .name = DRV_NAME,
  23035. + .match_table = talitos_match,
  23036. + .probe = talitos_probe,
  23037. + .remove = talitos_remove,
  23038. +};
  23039. +
  23040. +static int __init talitos_init(void)
  23041. +{
  23042. + return of_register_platform_driver(&talitos_driver);
  23043. +}
  23044. +
  23045. +static void __exit talitos_exit(void)
  23046. +{
  23047. + of_unregister_platform_driver(&talitos_driver);
  23048. +}
  23049. +#else
  23050. +/* Structure for a platform device driver */
  23051. +static struct platform_driver talitos_driver = {
  23052. + .probe = talitos_probe,
  23053. + .remove = talitos_remove,
  23054. + .driver = {
  23055. + .name = "fsl-sec2",
  23056. + }
  23057. +};
  23058. +
  23059. +static int __init talitos_init(void)
  23060. +{
  23061. + return platform_driver_register(&talitos_driver);
  23062. +}
  23063. +
  23064. +static void __exit talitos_exit(void)
  23065. +{
  23066. + platform_driver_unregister(&talitos_driver);
  23067. +}
  23068. +#endif
  23069. +
  23070. +module_init(talitos_init);
  23071. +module_exit(talitos_exit);
  23072. +
  23073. +MODULE_LICENSE("Dual BSD/GPL");
  23074. +MODULE_AUTHOR("kim.phillips@freescale.com");
  23075. +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
  23076. diff -Nur linux-2.6.29.1.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.29.1/crypto/ocf/talitos/talitos_dev.h
  23077. --- linux-2.6.29.1.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
  23078. +++ linux-2.6.29.1/crypto/ocf/talitos/talitos_dev.h 2009-04-20 20:01:21.636564372 +0200
  23079. @@ -0,0 +1,277 @@
  23080. +/*
  23081. + * Freescale SEC (talitos) device dependent data structures
  23082. + *
  23083. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  23084. + *
  23085. + * Redistribution and use in source and binary forms, with or without
  23086. + * modification, are permitted provided that the following conditions
  23087. + * are met:
  23088. + *
  23089. + * 1. Redistributions of source code must retain the above copyright
  23090. + * notice, this list of conditions and the following disclaimer.
  23091. + * 2. Redistributions in binary form must reproduce the above copyright
  23092. + * notice, this list of conditions and the following disclaimer in the
  23093. + * documentation and/or other materials provided with the distribution.
  23094. + * 3. The name of the author may not be used to endorse or promote products
  23095. + * derived from this software without specific prior written permission.
  23096. + *
  23097. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23098. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23099. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23100. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23101. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23102. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23103. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23104. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23105. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23106. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23107. + *
  23108. + */
  23109. +
  23110. +/* device ID register values */
  23111. +#define TALITOS_ID_SEC_2_0 0x40
  23112. +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
  23113. +
  23114. +/*
  23115. + * following num_channels, channel-fifo-depth, exec-unit-mask, and
  23116. + * descriptor-types-mask are for forward-compatibility with openfirmware
  23117. + * flat device trees
  23118. + */
  23119. +
  23120. +/*
  23121. + * num_channels : the number of channels available in each SEC version.
  23122. + */
  23123. +
  23124. +/* n.b. this driver requires these values be a power of 2 */
  23125. +#define TALITOS_NCHANNELS_SEC_1_0 4
  23126. +#define TALITOS_NCHANNELS_SEC_1_2 1
  23127. +#define TALITOS_NCHANNELS_SEC_2_0 4
  23128. +#define TALITOS_NCHANNELS_SEC_2_01 4
  23129. +#define TALITOS_NCHANNELS_SEC_2_1 4
  23130. +#define TALITOS_NCHANNELS_SEC_2_4 4
  23131. +
  23132. +/*
  23133. + * channel-fifo-depth : The number of descriptor
  23134. + * pointers a channel fetch fifo can hold.
  23135. + */
  23136. +#define TALITOS_CHFIFOLEN_SEC_1_0 1
  23137. +#define TALITOS_CHFIFOLEN_SEC_1_2 1
  23138. +#define TALITOS_CHFIFOLEN_SEC_2_0 24
  23139. +#define TALITOS_CHFIFOLEN_SEC_2_01 24
  23140. +#define TALITOS_CHFIFOLEN_SEC_2_1 24
  23141. +#define TALITOS_CHFIFOLEN_SEC_2_4 24
  23142. +
  23143. +/*
  23144. + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
  23145. + * are available. EU information should be encoded following the SEC's
  23146. + * EU_SEL0 bitfield documentation, i.e. as follows:
  23147. + *
  23148. + * bit 31 = set if SEC permits no-EU selection (should be always set)
  23149. + * bit 30 = set if SEC has the ARC4 EU (AFEU)
  23150. + * bit 29 = set if SEC has the des/3des EU (DEU)
  23151. + * bit 28 = set if SEC has the message digest EU (MDEU)
  23152. + * bit 27 = set if SEC has the random number generator EU (RNG)
  23153. + * bit 26 = set if SEC has the public key EU (PKEU)
  23154. + * bit 25 = set if SEC has the aes EU (AESU)
  23155. + * bit 24 = set if SEC has the Kasumi EU (KEU)
  23156. + *
  23157. + */
  23158. +#define TALITOS_HAS_EU_NONE (1<<0)
  23159. +#define TALITOS_HAS_EU_AFEU (1<<1)
  23160. +#define TALITOS_HAS_EU_DEU (1<<2)
  23161. +#define TALITOS_HAS_EU_MDEU (1<<3)
  23162. +#define TALITOS_HAS_EU_RNG (1<<4)
  23163. +#define TALITOS_HAS_EU_PKEU (1<<5)
  23164. +#define TALITOS_HAS_EU_AESU (1<<6)
  23165. +#define TALITOS_HAS_EU_KEU (1<<7)
  23166. +
  23167. +/* the corresponding masks for each SEC version */
  23168. +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
  23169. +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
  23170. +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
  23171. +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
  23172. +#define TALITOS_HAS_EUS_SEC_2_1 0xff
  23173. +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
  23174. +
  23175. +/*
  23176. + * descriptor-types-mask : The bitmask representing what descriptors
  23177. + * are available. Descriptor type information should be encoded
  23178. + * following the SEC's Descriptor Header Dword DESC_TYPE field
  23179. + * documentation, i.e. as follows:
  23180. + *
  23181. + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
  23182. + * bit 1 = set if SEC supports the ipsec_esp descriptor type
  23183. + * bit 2 = set if SEC supports the common_nonsnoop desc. type
  23184. + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
  23185. + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
  23186. + * bit 5 = set if SEC supports the srtp descriptor type
  23187. + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
  23188. + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
  23189. + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
  23190. + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
  23191. + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
  23192. + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
  23193. + *
  23194. + * ..and so on and so forth.
  23195. + */
  23196. +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
  23197. +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
  23198. +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
  23199. +
  23200. +/* the corresponding masks for each SEC version */
  23201. +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
  23202. +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
  23203. +
  23204. +/*
  23205. + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
  23206. + */
  23207. +
  23208. +/* global register offset addresses */
  23209. +#define TALITOS_ID 0x1020
  23210. +#define TALITOS_ID_HI 0x1024
  23211. +#define TALITOS_MCR 0x1030 /* master control register */
  23212. +#define TALITOS_MCR_HI 0x1038 /* master control register */
  23213. +#define TALITOS_MCR_SWR 0x1
  23214. +#define TALITOS_IMR 0x1008 /* interrupt mask register */
  23215. +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
  23216. +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
  23217. +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
  23218. +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
  23219. +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
  23220. +#define TALITOS_ISR 0x1010 /* interrupt status register */
  23221. +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
  23222. +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
  23223. +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
  23224. +#define TALITOS_ICR 0x1018 /* interrupt clear register */
  23225. +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
  23226. +
  23227. +/* channel register address stride */
  23228. +#define TALITOS_CH_OFFSET 0x100
  23229. +
  23230. +/* channel register offset addresses and bits */
  23231. +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
  23232. +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
  23233. +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
  23234. +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
  23235. +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
  23236. +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
  23237. +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
  23238. +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
  23239. +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
  23240. +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
  23241. +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
  23242. +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
  23243. +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
  23244. + * Descriptor Buffer (debug) */
  23245. +
  23246. +/* execution unit register offset addresses and bits */
  23247. +#define TALITOS_DEUSR 0x2028 /* DEU status register */
  23248. +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
  23249. +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
  23250. +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
  23251. +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
  23252. +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
  23253. +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
  23254. +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
  23255. +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
  23256. +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
  23257. +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
  23258. +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
  23259. +#define TALITOS_RNGSR 0xa028 /* RNG status register */
  23260. +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
  23261. +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
  23262. +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
  23263. +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
  23264. +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
  23265. +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
  23266. +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
  23267. +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
  23268. +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
  23269. +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
  23270. +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
  23271. +
  23272. +/* descriptor pointer entry */
  23273. +struct talitos_desc_ptr {
  23274. + u16 len; /* length */
  23275. + u8 extent; /* jump (to s/g link table) and extent */
  23276. + u8 res; /* reserved */
  23277. + u32 ptr; /* pointer */
  23278. +};
  23279. +
  23280. +/* descriptor */
  23281. +struct talitos_desc {
  23282. + u32 hdr; /* header */
  23283. + u32 res; /* reserved */
  23284. + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
  23285. +};
  23286. +
  23287. +/* talitos descriptor header (hdr) bits */
  23288. +
  23289. +/* primary execution unit select */
  23290. +#define TALITOS_SEL0_AFEU 0x10000000
  23291. +#define TALITOS_SEL0_DEU 0x20000000
  23292. +#define TALITOS_SEL0_MDEU 0x30000000
  23293. +#define TALITOS_SEL0_RNG 0x40000000
  23294. +#define TALITOS_SEL0_PKEU 0x50000000
  23295. +#define TALITOS_SEL0_AESU 0x60000000
  23296. +
  23297. +/* primary execution unit mode (MODE0) and derivatives */
  23298. +#define TALITOS_MODE0_AESU_CBC 0x00200000
  23299. +#define TALITOS_MODE0_AESU_ENC 0x00100000
  23300. +#define TALITOS_MODE0_DEU_CBC 0x00400000
  23301. +#define TALITOS_MODE0_DEU_3DES 0x00200000
  23302. +#define TALITOS_MODE0_DEU_ENC 0x00100000
  23303. +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
  23304. +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
  23305. +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
  23306. +#define TALITOS_MODE0_MDEU_MD5 0x00200000
  23307. +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
  23308. +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
  23309. +#define TALITOS_MODE0_MDEU_MD5_HMAC \
  23310. + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
  23311. +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
  23312. + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
  23313. +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
  23314. + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
  23315. +
  23316. +/* secondary execution unit select (SEL1) */
  23317. +/* it's MDEU or nothing */
  23318. +#define TALITOS_SEL1_MDEU 0x00030000
  23319. +
  23320. +/* secondary execution unit mode (MODE1) and derivatives */
  23321. +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
  23322. +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
  23323. +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
  23324. +#define TALITOS_MODE1_MDEU_MD5 0x00000200
  23325. +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
  23326. +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
  23327. +#define TALITOS_MODE1_MDEU_MD5_HMAC \
  23328. + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
  23329. +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
  23330. + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
  23331. +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
  23332. + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
  23333. +
  23334. +/* direction of overall data flow (DIR) */
  23335. +#define TALITOS_DIR_OUTBOUND 0x00000000
  23336. +#define TALITOS_DIR_INBOUND 0x00000002
  23337. +
  23338. +/* done notification (DN) */
  23339. +#define TALITOS_DONE_NOTIFY 0x00000001
  23340. +
  23341. +/* descriptor types */
  23342. +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
  23343. +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
  23344. +#define TD_TYPE_IPSEC_ESP (1 << 3)
  23345. +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
  23346. +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
  23347. +
  23348. +#define TALITOS_HDR_DONE_BITS 0xff000000
  23349. +
  23350. +#define DPRINTF(a...) do { \
  23351. + if (debug) { \
  23352. + printk("%s: ", sc ? \
  23353. + device_get_nameunit(sc->sc_cdev) : "talitos"); \
  23354. + printk(a); \
  23355. + } \
  23356. + } while (0)
  23357. diff -Nur linux-2.6.29.1.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.29.1/crypto/ocf/talitos/talitos_soft.h
  23358. --- linux-2.6.29.1.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
  23359. +++ linux-2.6.29.1/crypto/ocf/talitos/talitos_soft.h 2009-04-20 20:01:21.664565422 +0200
  23360. @@ -0,0 +1,77 @@
  23361. +/*
  23362. + * Freescale SEC data structures for integration with ocf-linux
  23363. + *
  23364. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  23365. + *
  23366. + * Redistribution and use in source and binary forms, with or without
  23367. + * modification, are permitted provided that the following conditions
  23368. + * are met:
  23369. + *
  23370. + * 1. Redistributions of source code must retain the above copyright
  23371. + * notice, this list of conditions and the following disclaimer.
  23372. + * 2. Redistributions in binary form must reproduce the above copyright
  23373. + * notice, this list of conditions and the following disclaimer in the
  23374. + * documentation and/or other materials provided with the distribution.
  23375. + * 3. The name of the author may not be used to endorse or promote products
  23376. + * derived from this software without specific prior written permission.
  23377. + *
  23378. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23379. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23380. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  23381. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23382. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  23383. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23384. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23385. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23386. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23387. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23388. + */
  23389. +
  23390. +/*
  23391. + * paired descriptor and associated crypto operation
  23392. + */
  23393. +struct desc_cryptop_pair {
  23394. + struct talitos_desc cf_desc; /* descriptor ptr */
  23395. + struct cryptop *cf_crp; /* cryptop ptr */
  23396. +};
  23397. +
  23398. +/*
  23399. + * Holds data specific to a single talitos device.
  23400. + */
  23401. +struct talitos_softc {
  23402. + softc_device_decl sc_cdev;
  23403. + struct platform_device *sc_dev; /* device backpointer */
  23404. + ocf_iomem_t sc_base_addr;
  23405. + int sc_irq;
  23406. + int sc_num; /* if we have multiple chips */
  23407. + int32_t sc_cid; /* crypto tag */
  23408. + u64 sc_chiprev; /* major/minor chip revision */
  23409. + int sc_nsessions;
  23410. + struct talitos_session *sc_sessions;
  23411. + int sc_num_channels;/* number of crypto channels */
  23412. + int sc_chfifo_len; /* channel fetch fifo len */
  23413. + int sc_exec_units; /* execution units mask */
  23414. + int sc_desc_types; /* descriptor types mask */
  23415. + /*
  23416. + * mutual exclusion for intra-channel resources, e.g. fetch fifos
  23417. + * the last entry is a meta-channel lock used by the channel scheduler
  23418. + */
  23419. + spinlock_t *sc_chnfifolock;
  23420. + /* sc_chnlastalgo contains last algorithm for that channel */
  23421. + int *sc_chnlastalg;
  23422. + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
  23423. + struct desc_cryptop_pair **sc_chnfifo;
  23424. +};
  23425. +
  23426. +struct talitos_session {
  23427. + u_int32_t ses_used;
  23428. + u_int32_t ses_klen; /* key length in bits */
  23429. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  23430. + u_int32_t ses_hmac[5]; /* hmac inner state */
  23431. + u_int32_t ses_hmac_len; /* hmac length */
  23432. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  23433. + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
  23434. +};
  23435. +
  23436. +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
  23437. +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  23438. diff -Nur linux-2.6.29.1.orig/crypto/ocf/uio.h linux-2.6.29.1/crypto/ocf/uio.h
  23439. --- linux-2.6.29.1.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
  23440. +++ linux-2.6.29.1/crypto/ocf/uio.h 2009-04-20 20:01:21.664565422 +0200
  23441. @@ -0,0 +1,54 @@
  23442. +#ifndef _OCF_UIO_H_
  23443. +#define _OCF_UIO_H_
  23444. +
  23445. +#include <linux/uio.h>
  23446. +
  23447. +/*
  23448. + * The linux uio.h doesn't have all we need. To be fully api compatible
  23449. + * with the BSD cryptodev, we need to keep this around. Perhaps this can
  23450. + * be moved back into the linux/uio.h
  23451. + *
  23452. + * Linux port done by David McCullough <david_mccullough@securecomputing.com>
  23453. + * Copyright (C) 2006-2007 David McCullough
  23454. + * Copyright (C) 2004-2005 Intel Corporation.
  23455. + *
  23456. + * LICENSE TERMS
  23457. + *
  23458. + * The free distribution and use of this software in both source and binary
  23459. + * form is allowed (with or without changes) provided that:
  23460. + *
  23461. + * 1. distributions of this source code include the above copyright
  23462. + * notice, this list of conditions and the following disclaimer;
  23463. + *
  23464. + * 2. distributions in binary form include the above copyright
  23465. + * notice, this list of conditions and the following disclaimer
  23466. + * in the documentation and/or other associated materials;
  23467. + *
  23468. + * 3. the copyright holder's name is not used to endorse products
  23469. + * built using this software without specific written permission.
  23470. + *
  23471. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  23472. + * may be distributed under the terms of the GNU General Public License (GPL),
  23473. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  23474. + *
  23475. + * DISCLAIMER
  23476. + *
  23477. + * This software is provided 'as is' with no explicit or implied warranties
  23478. + * in respect of its properties, including, but not limited to, correctness
  23479. + * and/or fitness for purpose.
  23480. + * ---------------------------------------------------------------------------
  23481. + */
  23482. +
  23483. +struct uio {
  23484. + struct iovec *uio_iov;
  23485. + int uio_iovcnt;
  23486. + off_t uio_offset;
  23487. + int uio_resid;
  23488. +#if 0
  23489. + enum uio_seg uio_segflg;
  23490. + enum uio_rw uio_rw;
  23491. + struct thread *uio_td;
  23492. +#endif
  23493. +};
  23494. +
  23495. +#endif
  23496. diff -Nur linux-2.6.29.1.orig/drivers/char/random.c linux-2.6.29.1/drivers/char/random.c
  23497. --- linux-2.6.29.1.orig/drivers/char/random.c 2009-04-02 22:55:27.000000000 +0200
  23498. +++ linux-2.6.29.1/drivers/char/random.c 2009-04-20 20:01:21.664565422 +0200
  23499. @@ -129,6 +129,9 @@
  23500. * unsigned int value);
  23501. * void add_interrupt_randomness(int irq);
  23502. *
  23503. + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  23504. + * int random_input_wait(void);
  23505. + *
  23506. * add_input_randomness() uses the input layer interrupt timing, as well as
  23507. * the event type information from the hardware.
  23508. *
  23509. @@ -140,6 +143,13 @@
  23510. * a better measure, since the timing of the disk interrupts are more
  23511. * unpredictable.
  23512. *
  23513. + * random_input_words() just provides a raw block of entropy to the input
  23514. + * pool, such as from a hardware entropy generator.
  23515. + *
  23516. + * random_input_wait() suspends the caller until such time as the
  23517. + * entropy pool falls below the write threshold, and returns a count of how
  23518. + * much entropy (in bits) is needed to sustain the pool.
  23519. + *
  23520. * All of these routines try to estimate how many bits of randomness a
  23521. * particular randomness source. They do this by keeping track of the
  23522. * first and second order deltas of the event timings.
  23523. @@ -708,6 +718,61 @@
  23524. }
  23525. #endif
  23526. +/*
  23527. + * random_input_words - add bulk entropy to pool
  23528. + *
  23529. + * @buf: buffer to add
  23530. + * @wordcount: number of __u32 words to add
  23531. + * @ent_count: total amount of entropy (in bits) to credit
  23532. + *
  23533. + * this provides bulk input of entropy to the input pool
  23534. + *
  23535. + */
  23536. +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  23537. +{
  23538. + mix_pool_bytes(&input_pool, buf, wordcount*4);
  23539. +
  23540. + credit_entropy_bits(&input_pool, ent_count);
  23541. +
  23542. + DEBUG_ENT("crediting %d bits => %d\n",
  23543. + ent_count, input_pool.entropy_count);
  23544. + /*
  23545. + * Wake up waiting processes if we have enough
  23546. + * entropy.
  23547. + */
  23548. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  23549. + wake_up_interruptible(&random_read_wait);
  23550. +}
  23551. +EXPORT_SYMBOL(random_input_words);
  23552. +
  23553. +/*
  23554. + * random_input_wait - wait until random needs entropy
  23555. + *
  23556. + * this function sleeps until the /dev/random subsystem actually
  23557. + * needs more entropy, and then return the amount of entropy
  23558. + * that it would be nice to have added to the system.
  23559. + */
  23560. +int random_input_wait(void)
  23561. +{
  23562. + int count;
  23563. +
  23564. + wait_event_interruptible(random_write_wait,
  23565. + input_pool.entropy_count < random_write_wakeup_thresh);
  23566. +
  23567. + count = random_write_wakeup_thresh - input_pool.entropy_count;
  23568. +
  23569. + /* likely we got woken up due to a signal */
  23570. + if (count <= 0) count = random_read_wakeup_thresh;
  23571. +
  23572. + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
  23573. + count,
  23574. + input_pool.entropy_count, random_write_wakeup_thresh);
  23575. +
  23576. + return count;
  23577. +}
  23578. +EXPORT_SYMBOL(random_input_wait);
  23579. +
  23580. +
  23581. #define EXTRACT_SIZE 10
  23582. /*********************************************************************
  23583. diff -Nur linux-2.6.29.1.orig/fs/fcntl.c linux-2.6.29.1/fs/fcntl.c
  23584. --- linux-2.6.29.1.orig/fs/fcntl.c 2009-04-02 22:55:27.000000000 +0200
  23585. +++ linux-2.6.29.1/fs/fcntl.c 2009-04-20 20:01:21.668566770 +0200
  23586. @@ -140,6 +140,7 @@
  23587. }
  23588. return ret;
  23589. }
  23590. +EXPORT_SYMBOL(sys_dup);
  23591. #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME)
  23592. diff -Nur linux-2.6.29.1.orig/include/linux/miscdevice.h linux-2.6.29.1/include/linux/miscdevice.h
  23593. --- linux-2.6.29.1.orig/include/linux/miscdevice.h 2009-04-02 22:55:27.000000000 +0200
  23594. +++ linux-2.6.29.1/include/linux/miscdevice.h 2009-04-20 20:02:00.530996185 +0200
  23595. @@ -12,6 +12,7 @@
  23596. #define APOLLO_MOUSE_MINOR 7
  23597. #define PC110PAD_MINOR 9
  23598. /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
  23599. +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
  23600. #define WATCHDOG_MINOR 130 /* Watchdog timer */
  23601. #define TEMP_MINOR 131 /* Temperature Sensor */
  23602. #define RTC_MINOR 135
  23603. diff -Nur linux-2.6.29.1.orig/include/linux/random.h linux-2.6.29.1/include/linux/random.h
  23604. --- linux-2.6.29.1.orig/include/linux/random.h 2009-04-02 22:55:27.000000000 +0200
  23605. +++ linux-2.6.29.1/include/linux/random.h 2009-04-20 20:01:21.680566903 +0200
  23606. @@ -34,6 +34,30 @@
  23607. /* Clear the entropy pool and associated counters. (Superuser only.) */
  23608. #define RNDCLEARPOOL _IO( 'R', 0x06 )
  23609. +#ifdef CONFIG_FIPS_RNG
  23610. +
  23611. +/* Size of seed value - equal to AES blocksize */
  23612. +#define AES_BLOCK_SIZE_BYTES 16
  23613. +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
  23614. +/* Size of AES key */
  23615. +#define KEY_SIZE_BYTES 16
  23616. +
  23617. +/* ioctl() structure used by FIPS 140-2 Tests */
  23618. +struct rand_fips_test {
  23619. + unsigned char key[KEY_SIZE_BYTES]; /* Input */
  23620. + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
  23621. + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
  23622. + unsigned char result[SEED_SIZE_BYTES]; /* Output */
  23623. +};
  23624. +
  23625. +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
  23626. +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
  23627. +
  23628. +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
  23629. +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
  23630. +
  23631. +#endif /* #ifdef CONFIG_FIPS_RNG */
  23632. +
  23633. struct rand_pool_info {
  23634. int entropy_count;
  23635. int buf_size;
  23636. @@ -50,6 +74,10 @@
  23637. unsigned int value);
  23638. extern void add_interrupt_randomness(int irq);
  23639. +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
  23640. +extern int random_input_wait(void);
  23641. +#define HAS_RANDOM_INPUT_WAIT 1
  23642. +
  23643. extern void get_random_bytes(void *buf, int nbytes);
  23644. void generate_random_uuid(unsigned char uuid_out[16]);