| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545 | diff -Nur linux-2.6.36.orig/crypto/Kconfig linux-2.6.36/crypto/Kconfig--- linux-2.6.36.orig/crypto/Kconfig	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/crypto/Kconfig	2010-11-09 20:28:04.004996902 +0100@@ -845,3 +845,6 @@ source "drivers/crypto/Kconfig"  endif	# if CRYPTO++source "crypto/ocf/Kconfig"+diff -Nur linux-2.6.36.orig/crypto/Makefile linux-2.6.36/crypto/Makefile--- linux-2.6.36.orig/crypto/Makefile	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/crypto/Makefile	2010-11-09 20:28:04.014995662 +0100@@ -86,6 +86,8 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o +obj-$(CONFIG_OCF_OCF) += ocf/+ # # generic algorithms and the async_tx api #diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.c linux-2.6.36/crypto/ocf/c7108/aes-7108.c--- linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/c7108/aes-7108.c	2010-11-09 20:28:04.061247304 +0100@@ -0,0 +1,839 @@+/*+ * Copyright (C) 2006 Micronas USA+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+ */++//#include <linux/config.h>+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/sched.h>+#include <linux/wait.h>+#include <linux/crypto.h>+#include <linux/mm.h>+#include <linux/skbuff.h>+#include <linux/random.h>+#include <asm/io.h>+#include <asm/delay.h>+//#include <asm/scatterlist.h>+#include <linux/scatterlist.h>+#include <linux/dma-mapping.h>+#include <linux/highmem.h>+#include <cryptodev.h>+#include <uio.h>+#include <aes-7108.h>++/* Runtime mode */+static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;+//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;++static int32_t c7108_id = -1;+static struct cipher_7108 **c7108_sessions = NULL;+static u_int32_t c7108_sesnum = 0;+static unsigned long iobar;++/* Crypto entry points */+static	int c7108_process(void *, struct cryptop *, int);+static	int c7108_newsession(void *, u_int32_t *, struct cryptoini *);+static	int c7108_freesession(void *, u_int64_t);++/* Globals */+static int debug = 0;+static spinlock_t csr_mutex;++/* Generic controller-based lock */+#define AES_LOCK()\+          spin_lock(&csr_mutex)+#define AES_UNLOCK()\+          spin_unlock(&csr_mutex)++/* 7108 AES register access */+#define c7108_reg_wr8(a,d)   iowrite8(d, (void*)(iobar+(a)))+#define c7108_reg_wr16(a,d)  iowrite16(d, (void*)(iobar+(a)))+#define c7108_reg_wr32(a,d)  iowrite32(d, (void*)(iobar+(a)))+#define c7108_reg_rd8(a)     ioread8((void*)(iobar+(a)))+#define c7108_reg_rd16(a)    ioread16((void*)(iobar+(a)))+#define c7108_reg_rd32(a)    ioread32((void*)(iobar+(a)))++static int +c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr)+{+        int i, nw=0;+	nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4);+	for ( i = 0; i < nw; i++) { +	    k32ptr[i] =    (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) | +		           (k8ptr[i+1] << 8)  | k8ptr[i];+	    +	}+	return 0;+}++static int +c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr)+{+        int i, nb=0;+	u8* ptr = (u8*)k32ptr;+	nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16);+	for ( i = 0; i < nb; i++)+	    k8ptr[i] = ptr[i];+	return 0;+}++static int+c7108_aes_setup_dma(u32 src, u32 dst, u32 len)+{+        if (len < 16) {+	    printk("len < 16\n");+	    return -10;+	}+	if (len % 16) {+	    printk("len not multiple of 16\n");+	    return -11;+	}	+	c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src);+	c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16));+	c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst);+	c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16));+	c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1));++	return 0;+}++static int+c7108_aes_set_hw_iv(u8 iv[16])+{+        c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0]));+	c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2]));+	c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4]));+	c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6]));+	c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8]));+	c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10]));+	c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12]));+	c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14]));++    return 0;+}++static void+c7108_aes_read_dkey(u32 * dkey)+{+        dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) | +	           c7108_reg_rd16(C7108_AES_EKEY0_LO);+	dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) | +	           c7108_reg_rd16(C7108_AES_EKEY1_LO);+	dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) | +	           c7108_reg_rd16(C7108_AES_EKEY2_LO);+	dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) | +	           c7108_reg_rd16(C7108_AES_EKEY3_LO);+	dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) | +                   c7108_reg_rd16(C7108_AES_EKEY4_LO);+	dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) | +                   c7108_reg_rd16(C7108_AES_EKEY5_LO);+	dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) | +                   c7108_reg_rd16(C7108_AES_EKEY6_LO);+	dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) | +                   c7108_reg_rd16(C7108_AES_EKEY7_LO);+}++static int+c7108_aes_cipher(int op,+		 u32 dst,+		 u32 src,+		 u32 len,+		 int klen,+		 u16 mode,+		 u32 key[8],+		 u8 iv[16])+{+        int rv = 0, cnt=0;+	u16 ctrl = 0, stat = 0;++	AES_LOCK();++	/* Setup key length */+	if (klen == 128) {+	    ctrl |= C7108_AES_KEY_LEN_128;+	} else if (klen == 192) {+	    ctrl |= C7108_AES_KEY_LEN_192;+	} else if (klen == 256) {+	    ctrl |= C7108_AES_KEY_LEN_256;+	} else {+	    AES_UNLOCK();+	    return -3;+	}+	+	/* Check opcode */+	if (C7108_AES_ENCRYPT == op) {+	    ctrl |= C7108_AES_ENCRYPT;+	} else if (C7108_AES_DECRYPT == op) {+	    ctrl |= C7108_AES_DECRYPT;+	} else {+	    AES_UNLOCK();+	    return -4;+	}+	+	/* check mode */+	if ( (mode != C7108_AES_CTRL_MODE_CBC) &&+	     (mode != C7108_AES_CTRL_MODE_CFB) &&+	     (mode != C7108_AES_CTRL_MODE_OFB) &&+	     (mode != C7108_AES_CTRL_MODE_CTR) && +	     (mode != C7108_AES_CTRL_MODE_ECB) ) { +	    AES_UNLOCK();	    +	    return -5;+	}+	+	/* Now set mode */+	ctrl |= mode;+	+	/* For CFB, OFB, and CTR, neither backward key+	 * expansion nor key inversion is required.+	 */+	if ( (C7108_AES_DECRYPT == op) &&  +	     (C7108_AES_CTRL_MODE_CBC == mode ||+	      C7108_AES_CTRL_MODE_ECB == mode ) ){ ++	    /* Program Key */+	    c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]);+	    c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]);+	    c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]);+	    c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]);+	    c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]);+	    c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]);+	    c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16));+	    +	    +	    if (192 == klen) { +		c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]);+		c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16));+		c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]);+		c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16));+		+	    } else if (256 == klen) {+		/* 256 */+		c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]);+		c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16));+		c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]);+		c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16));+		+	    }+	    +	} else { +	    /* Program Key */+	    c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]);+	    c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]);+	    c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]);+	    c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]);+	    c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]);+	    c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]);+	    c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]);+	    c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16));+	    c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]);+	    c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16));+	    +	}+	+	/* Set IV always */+	c7108_aes_set_hw_iv(iv);+	+	/* Program DMA addresses */+	if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) { +	    AES_UNLOCK();+	    return rv;+	}++	+	/* Start AES cipher */+	c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO);+	+	//printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO);+	do {+	    /* TODO: interrupt mode */+	    //        printk("aes_stat=0x%x\n", stat);+	    //udelay(100);+	} while ((cnt++ < 1000000) && +		 !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE));+++	if ((mode == C7108_AES_CTRL_MODE_ECB)||+	    (mode == C7108_AES_CTRL_MODE_CBC)) { +	    /* Save out key when the lock is held ... */+	    c7108_aes_read_dkey(key);+	}+	+	AES_UNLOCK();+	return 0;+	+}++/*+ * Generate a new crypto device session.+ */+static int+c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)+{+	struct cipher_7108 **swd;+	u_int32_t i;+	char *algo;+	int mode, xfm_type;++	dprintk("%s()\n", __FUNCTION__);+	if (sid == NULL || cri == NULL) {+		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	if (c7108_sessions) {+		for (i = 1; i < c7108_sesnum; i++)+			if (c7108_sessions[i] == NULL)+				break;+	} else+		i = 1;		/* NB: to silence compiler warning */++	if (c7108_sessions == NULL || i == c7108_sesnum) {+	    if (c7108_sessions == NULL) {+		i = 1; /* We leave c7108_sessions[0] empty */+		c7108_sesnum = CRYPTO_SW_SESSIONS;+	    } else+		c7108_sesnum *= 2;+	    +	    swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *), +			  GFP_ATOMIC);+	    if (swd == NULL) {+		/* Reset session number */+		if (c7108_sesnum == CRYPTO_SW_SESSIONS)+		    c7108_sesnum = 0;+		else+		    c7108_sesnum /= 2;+		dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+		return ENOBUFS;+	    }+	    memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *));+	    +	    /* Copy existing sessions */+	    if (c7108_sessions) {+		memcpy(swd, c7108_sessions,+		       (c7108_sesnum / 2) * sizeof(struct cipher_7108 *));+		kfree(c7108_sessions);+	    }+	    +	    c7108_sessions = swd;++	}+	+	swd = &c7108_sessions[i];+	*sid = i;++	while (cri) {+		*swd = (struct cipher_7108 *) +		    kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC);+		if (*swd == NULL) {+		    c7108_freesession(NULL, i);+		    dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		    return ENOBUFS;+		}+		memset(*swd, 0, sizeof(struct cipher_7108));++		algo = NULL;+		mode = 0;+		xfm_type = HW_TYPE_CIPHER;++		switch (cri->cri_alg) {++		case CRYPTO_AES_CBC:+			algo = "aes";+			mode = CRYPTO_TFM_MODE_CBC;+			c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;+			break;+#if 0+		case CRYPTO_AES_CTR:+			algo = "aes_ctr";+			mode = CRYPTO_TFM_MODE_CBC;+			c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;+			break;+		case CRYPTO_AES_ECB:+			algo = "aes_ecb";+			mode = CRYPTO_TFM_MODE_CBC;+			c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB;+			break;+		case CRYPTO_AES_OFB:+			algo = "aes_ofb";+			mode = CRYPTO_TFM_MODE_CBC;+			c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB;+			break;+		case CRYPTO_AES_CFB:+			algo = "aes_cfb";+			mode = CRYPTO_TFM_MODE_CBC;+			c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB;+			break;+#endif+		default:+		        printk("unsupported crypto algorithm: %d\n", +			       cri->cri_alg);+			return -EINVAL;+			break;+		}+++		if (!algo || !*algo) {+		    printk("cypher_7108_crypto: Unknown algo 0x%x\n", +			   cri->cri_alg);+		    c7108_freesession(NULL, i);+		    return EINVAL;+		}+		+		if (xfm_type == HW_TYPE_CIPHER) {+		    if (debug) {+			dprintk("%s key:", __FUNCTION__);+			for (i = 0; i < (cri->cri_klen + 7) / 8; i++)+			    dprintk("%s0x%02x", (i % 8) ? " " : "\n    ",+				    cri->cri_key[i]);+			dprintk("\n");+		    }++		} else if (xfm_type == SW_TYPE_HMAC || +			   xfm_type == SW_TYPE_HASH) {+		    printk("cypher_7108_crypto: HMAC unsupported!\n");+		    return -EINVAL;+		    c7108_freesession(NULL, i);+		} else {+		    printk("cypher_7108_crypto: "+			   "Unhandled xfm_type %d\n", xfm_type);+		    c7108_freesession(NULL, i);+		    return EINVAL;+		}+		+		(*swd)->cri_alg = cri->cri_alg;+		(*swd)->xfm_type = xfm_type;+		+		cri = cri->cri_next;+		swd = &((*swd)->next);+	}+	return 0;+}++/*+ * Free a session.+ */+static int+c7108_freesession(void *arg, u_int64_t tid)+{+	struct cipher_7108 *swd;+	u_int32_t sid = CRYPTO_SESID2LID(tid);++	dprintk("%s()\n", __FUNCTION__);+	if (sid > c7108_sesnum || c7108_sessions == NULL ||+			c7108_sessions[sid] == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return(EINVAL);+	}++	/* Silently accept and return */+	if (sid == 0)+		return(0);++	while ((swd = c7108_sessions[sid]) != NULL) {+		c7108_sessions[sid] = swd->next;+		kfree(swd);+	}+	return 0;+}++/*+ * Process a hardware request.+ */+static int+c7108_process(void *arg, struct cryptop *crp, int hint)+{+	struct cryptodesc *crd;+	struct cipher_7108 *sw;+	u_int32_t lid;+	int type;+	u32 hwkey[8];++#define SCATTERLIST_MAX 16+	struct scatterlist sg[SCATTERLIST_MAX];+	int sg_num, sg_len, skip;+	struct sk_buff *skb = NULL;+	struct uio *uiop = NULL;++	dprintk("%s()\n", __FUNCTION__);+	/* Sanity check */+	if (crp == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	crp->crp_etype = 0;++	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	}++	lid = crp->crp_sid & 0xffffffff;+	if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL ||+			c7108_sessions[lid] == NULL) {+		crp->crp_etype = ENOENT;+		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);+		goto done;+	}++	/*+	 * do some error checking outside of the loop for SKB and IOV+	 * processing this leaves us with valid skb or uiop pointers+	 * for later+	 */+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		skb = (struct sk_buff *) crp->crp_buf;+		if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {+			printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", +			       __FILE__, __LINE__,+			       skb_shinfo(skb)->nr_frags);+			goto done;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		uiop = (struct uio *) crp->crp_buf;+		if (uiop->uio_iovcnt > SCATTERLIST_MAX) {+			printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", +			       __FILE__, __LINE__,+			       uiop->uio_iovcnt);+			goto done;+		}+	}++	/* Go through crypto descriptors, processing as we go */+	for (crd = crp->crp_desc; crd; crd = crd->crd_next) {+	    /*+	     * Find the crypto context.+	     *+	     * XXX Note that the logic here prevents us from having+	     * XXX the same algorithm multiple times in a session+	     * XXX (or rather, we can but it won't give us the right+	     * XXX results). To do that, we'd need some way of differentiating+	     * XXX between the various instances of an algorithm (so we can+	     * XXX locate the correct crypto context).+	     */+	    for (sw = c7108_sessions[lid]; +		 sw && sw->cri_alg != crd->crd_alg;+		 sw = sw->next)+		;+	    +	    /* No such context ? */+	    if (sw == NULL) {+		crp->crp_etype = EINVAL;+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		goto done;+	    }+	    +	    skip = crd->crd_skip;+	    +	    /*+	     * setup the SG list skip from the start of the buffer+	     */+	    memset(sg, 0, sizeof(sg));+	    if (crp->crp_flags & CRYPTO_F_SKBUF) {+		int i, len;+		type = CRYPTO_BUF_SKBUF;+		+		sg_num = 0;+		sg_len = 0;++		if (skip < skb_headlen(skb)) {+		    //sg[sg_num].page   = virt_to_page(skb->data + skip);+			//sg[sg_num].offset = offset_in_page(skb->data + skip);+		    len = skb_headlen(skb) - skip;+		    if (len + sg_len > crd->crd_len)+			len = crd->crd_len - sg_len;+		    //sg[sg_num].length = len;+		    sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip));+			sg_len += sg[sg_num].length;+		    sg_num++;+		    skip = 0;+		} else+		    skip -= skb_headlen(skb);+		+		for (i = 0; sg_len < crd->crd_len &&+			 i < skb_shinfo(skb)->nr_frags &&+			 sg_num < SCATTERLIST_MAX; i++) {+		    if (skip < skb_shinfo(skb)->frags[i].size) {+			//sg[sg_num].page   = skb_shinfo(skb)->frags[i].page;+			//sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip;+			len = skb_shinfo(skb)->frags[i].size - skip;+			if (len + sg_len > crd->crd_len)+			    len = crd->crd_len - sg_len;+			//sg[sg_num].length = len;+			sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip);+			sg_len += sg[sg_num].length;+			sg_num++;+			skip = 0;+		    } else+			skip -= skb_shinfo(skb)->frags[i].size;+		}+	    } else if (crp->crp_flags & CRYPTO_F_IOV) {+		int len;+		type = CRYPTO_BUF_IOV;+		sg_len = 0;+		for (sg_num = 0; sg_len < crd->crd_len &&+			 sg_num < uiop->uio_iovcnt &&+			 sg_num < SCATTERLIST_MAX; sg_num++) {+		    if (skip < uiop->uio_iov[sg_num].iov_len) {+			//sg[sg_num].page   =			    virt_to_page(uiop->uio_iov[sg_num].iov_base+skip);+			//sg[sg_num].offset =			   offset_in_page(uiop->uio_iov[sg_num].iov_base+skip);+			len = uiop->uio_iov[sg_num].iov_len - skip;+			if (len + sg_len > crd->crd_len)+			    len = crd->crd_len - sg_len;+			//sg[sg_num].length = len;+			sg_set_page(&sg[sg_num], virt_to_page(uiop->uio_iov[sg_num].iov_base+skip), len, offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));+			sg_len += sg[sg_num].length;+			skip = 0;+		    } else +			skip -= uiop->uio_iov[sg_num].iov_len;+		}+	    } else {+		type = CRYPTO_BUF_CONTIG;+		//sg[0].page   = virt_to_page(crp->crp_buf + skip);+		//sg[0].offset = offset_in_page(crp->crp_buf + skip);+		sg_len = (crp->crp_ilen - skip);+		if (sg_len > crd->crd_len)+		    sg_len = crd->crd_len;+		//sg[0].length = sg_len;+		sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip));+		sg_num = 1;+	    }+	    +	    +	    switch (sw->xfm_type) {++	    case HW_TYPE_CIPHER: {++		unsigned char iv[64];+		unsigned char *ivp = iv;+		int i;+		int ivsize = 16;    /* fixed for AES */+		int blocksize = 16; /* fixed for AES */++		if (sg_len < blocksize) {+		    crp->crp_etype = EINVAL;+		    dprintk("%s,%d: EINVAL len %d < %d\n", +			    __FILE__, __LINE__,+			    sg_len, +			    blocksize);+		    goto done;+		}+		+		if (ivsize > sizeof(iv)) {+		    crp->crp_etype = EINVAL;+		    dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		    goto done;+		}+		+		if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */+		    +		    if (crd->crd_flags & CRD_F_IV_EXPLICIT) {+			ivp = crd->crd_iv;+		    } else {+			get_random_bytes(ivp, ivsize);+		    }+		    /*+		     * do we have to copy the IV back to the buffer ?+		     */+		    if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {+			    crypto_copyback(crp->crp_buf,+					  crd->crd_inject,+					  ivsize,+					  (caddr_t)ivp);+		    }++		    c7108_xlate_key(crd->crd_klen,+				    (u8*)crd->crd_key, (u32*)hwkey);++		    /* Encrypt SG list */+		    for (i = 0; i < sg_num; i++) { +			sg[i].dma_address = +			    dma_map_single(NULL, +					   kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL);+#if 0							   +			printk("sg[%d]:0x%08x, off 0x%08x "+			       "kmap 0x%08x phys 0x%08x\n", +			       i, sg[i].page, sg[i].offset,+			       kmap(sg[i].page) + sg[i].offset,+			       sg[i].dma_address);+#endif+			c7108_aes_cipher(C7108_AES_ENCRYPT,+					 sg[i].dma_address,+					 sg[i].dma_address,+					 sg_len,+					 crd->crd_klen,+					 c7108_crypto_mode,+					 hwkey,+					 ivp);++			if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)||+			    (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) { +			    /* Read back expanded key and cache it in key+			     * context.+			     * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB)+			     *       where you set the key once.+			     */+			    c7108_cache_key(crd->crd_klen, +					    (u32*)hwkey, (u8*)crd->crd_key);+#if 0+			    printk("%s expanded key:", __FUNCTION__);+			    for (i = 0; i < (crd->crd_klen + 7) / 8; i++)+				printk("%s0x%02x", (i % 8) ? " " : "\n    ",+				       crd->crd_key[i]);+			    printk("\n");+#endif+			}+		    }+		}+		else { /*decrypt */++		    if (crd->crd_flags & CRD_F_IV_EXPLICIT) {+			ivp = crd->crd_iv;+		    } else {+			crypto_copydata(crp->crp_buf, crd->crd_inject,+				  ivsize, (caddr_t)ivp);+		    }++		    c7108_xlate_key(crd->crd_klen,+				    (u8*)crd->crd_key, (u32*)hwkey);++		    /* Decrypt SG list */+		    for (i = 0; i < sg_num; i++) { +			sg[i].dma_address = +			    dma_map_single(NULL, +					   kmap(sg_page(&sg[i])) + sg[i].offset,+					   sg_len, DMA_BIDIRECTIONAL);++#if 0+			printk("sg[%d]:0x%08x, off 0x%08x "+			       "kmap 0x%08x phys 0x%08x\n", +			       i, sg[i].page, sg[i].offset,+			       kmap(sg[i].page) + sg[i].offset,+			       sg[i].dma_address);+#endif+			c7108_aes_cipher(C7108_AES_DECRYPT,+					 sg[i].dma_address,+					 sg[i].dma_address,+					 sg_len,+					 crd->crd_klen,+					 c7108_crypto_mode,+					 hwkey,+					 ivp);+		    }+		}+	    } break;+	    case SW_TYPE_HMAC:+	    case SW_TYPE_HASH:+		crp->crp_etype = EINVAL;+		goto done;+		break;+		+	    case SW_TYPE_COMP:+		crp->crp_etype = EINVAL;+		goto done;+		break;+		+	    default:+		/* Unknown/unsupported algorithm */+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	    }+	}+	+done:+	crypto_done(crp);+	return 0;+}++static struct {                                                                                                                 +	softc_device_decl sc_dev;                                                                                               +} a7108dev;++static device_method_t a7108_methods = {                                                                                          +/* crypto device methods */                                                                                             +	DEVMETHOD(cryptodev_newsession, c7108_newsession),                                                                  +	DEVMETHOD(cryptodev_freesession, c7108_freesession),                                                             +	DEVMETHOD(cryptodev_process, c7108_process),                                                                     +	DEVMETHOD(cryptodev_kprocess, NULL) +};   ++static int+cypher_7108_crypto_init(void)+{+	dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init);+	+	iobar = (unsigned long)ioremap(CCU_AES_REG_BASE, 0x4000);+	printk("7108: AES @ 0x%08x (0x%08x phys) %s mode\n", +	       iobar, CCU_AES_REG_BASE, +	       c7108_crypto_mode & C7108_AES_CTRL_MODE_CBC ? "CBC" :+	       c7108_crypto_mode & C7108_AES_CTRL_MODE_ECB ? "ECB" : +	       c7108_crypto_mode & C7108_AES_CTRL_MODE_CTR ? "CTR" : +	       c7108_crypto_mode & C7108_AES_CTRL_MODE_CFB ? "CFB" : +	       c7108_crypto_mode & C7108_AES_CTRL_MODE_OFB ? "OFB" : "???");+	csr_mutex  = SPIN_LOCK_UNLOCKED;++	memset(&a7108dev, 0, sizeof(a7108dev));                                                                                     +	softc_device_init(&a7108dev, "aes7108", 0, a7108_methods);++       	c7108_id = crypto_get_driverid(softc_get_device(&a7108dev), CRYPTOCAP_F_HARDWARE);+	if (c7108_id < 0)+		panic("7108: crypto device cannot initialize!");++//	crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0, c7108_newsession, c7108_freesession, c7108_process, NULL);+	crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0);++	return(0);+}++static void+cypher_7108_crypto_exit(void)+{+	dprintk("%s()\n", __FUNCTION__);+	crypto_unregister_all(c7108_id);+	c7108_id = -1;+}++module_init(cypher_7108_crypto_init);+module_exit(cypher_7108_crypto_exit);++MODULE_LICENSE("Dual BSD/GPL");+MODULE_DESCRIPTION("Cypher 7108 Crypto (OCF module for kernel crypto)");diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.h linux-2.6.36/crypto/ocf/c7108/aes-7108.h--- linux-2.6.36.orig/crypto/ocf/c7108/aes-7108.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/c7108/aes-7108.h	2010-11-09 20:28:04.102495305 +0100@@ -0,0 +1,134 @@+/*+ * Copyright (C) 2006 Micronas USA+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+ */++#ifndef __AES_7108_H__+#define __AES_7108_H__++/* Cypher 7108 AES Controller Hardware */+#define CCU_REG_BASE       0x1b500000	+#define CCU_AES_REG_BASE   (CCU_REG_BASE + 0x100)+#define C7108_AES_KEY0_LO        (0x0000) +#define C7108_AES_KEY0_HI        (0x0004) +#define C7108_AES_KEY1_LO        (0x0008) +#define C7108_AES_KEY1_HI        (0x000c) +#define C7108_AES_KEY2_LO        (0x0010) +#define C7108_AES_KEY2_HI        (0x0014) +#define C7108_AES_KEY3_LO        (0x0018) +#define C7108_AES_KEY3_HI        (0x001c) +#define C7108_AES_KEY4_LO        (0x0020) +#define C7108_AES_KEY4_HI        (0x0024) +#define C7108_AES_KEY5_LO        (0x0028) +#define C7108_AES_KEY5_HI        (0x002c) +#define C7108_AES_KEY6_LO        (0x0030) +#define C7108_AES_KEY6_HI        (0x0034) +#define C7108_AES_KEY7_LO        (0x0038) +#define C7108_AES_KEY7_HI        (0x003c) +#define C7108_AES_IV0_LO         (0x0040) +#define C7108_AES_IV0_HI         (0x0044) +#define C7108_AES_IV1_LO         (0x0048) +#define C7108_AES_IV1_HI         (0x004c) +#define C7108_AES_IV2_LO         (0x0050) +#define C7108_AES_IV2_HI         (0x0054) +#define C7108_AES_IV3_LO         (0x0058) +#define C7108_AES_IV3_HI         (0x005c) ++#define C7108_AES_DMA_SRC0_LO    (0x0068) /* Bits 0:15 */+#define C7108_AES_DMA_SRC0_HI    (0x006c) /* Bits 27:16 */+#define C7108_AES_DMA_DST0_LO    (0x0070) /* Bits 0:15 */+#define C7108_AES_DMA_DST0_HI    (0x0074) /* Bits 27:16 */+#define C7108_AES_DMA_LEN        (0x0078)  /*Bytes:(Count+1)x16 */++/* AES/Copy engine control register */+#define C7108_AES_CTRL           (0x007c) /* AES control */+#define C7108_AES_CTRL_RS        (1<<0)     /* Which set of src/dst to use */++/* AES Cipher mode, controlled by setting Bits 2:0 */+#define C7108_AES_CTRL_MODE_CBC     0+#define C7108_AES_CTRL_MODE_CFB     (1<<0)+#define C7108_AES_CTRL_MODE_OFB     (1<<1)+#define C7108_AES_CTRL_MODE_CTR     ((1<<0)|(1<<1))+#define C7108_AES_CTRL_MODE_ECB     (1<<2)++/* AES Key length , Bits 5:4 */+#define C7108_AES_KEY_LEN_128         0       /* 00 */+#define C7108_AES_KEY_LEN_192         (1<<4)  /* 01 */+#define C7108_AES_KEY_LEN_256         (1<<5)  /* 10 */++/* AES Operation (crypt/decrypt), Bit 3 */+#define C7108_AES_DECRYPT             (1<<3)   /* Clear for encrypt */+#define C7108_AES_ENCRYPT              0       +#define C7108_AES_INTR                (1<<13) /* Set on done trans from 0->1*/+#define C7108_AES_GO                  (1<<14) /* Run */+#define C7108_AES_OP_DONE             (1<<15) /* Set when complete */+++/* Expanded key registers */+#define C7108_AES_EKEY0_LO            (0x0080)+#define C7108_AES_EKEY0_HI            (0x0084)+#define C7108_AES_EKEY1_LO            (0x0088)+#define C7108_AES_EKEY1_HI            (0x008c)+#define C7108_AES_EKEY2_LO            (0x0090)+#define C7108_AES_EKEY2_HI            (0x0094)+#define C7108_AES_EKEY3_LO            (0x0098)+#define C7108_AES_EKEY3_HI            (0x009c)+#define C7108_AES_EKEY4_LO            (0x00a0)+#define C7108_AES_EKEY4_HI            (0x00a4)+#define C7108_AES_EKEY5_LO            (0x00a8)+#define C7108_AES_EKEY5_HI            (0x00ac)+#define C7108_AES_EKEY6_LO            (0x00b0)+#define C7108_AES_EKEY6_HI            (0x00b4)+#define C7108_AES_EKEY7_LO            (0x00b8)+#define C7108_AES_EKEY7_HI            (0x00bc)+#define C7108_AES_OK                  (0x00fc) /* Reset: "OK" */++#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)++/* Software session entry */++#define HW_TYPE_CIPHER	0+#define SW_TYPE_HMAC	1+#define SW_TYPE_AUTH2	2+#define SW_TYPE_HASH	3+#define SW_TYPE_COMP	4++struct cipher_7108 {+	int			xfm_type;+	int			cri_alg;+	union {+		struct {+			char sw_key[HMAC_BLOCK_LEN];+			int  sw_klen;+			int  sw_authlen;+		} hmac;+	} u;+	struct cipher_7108	*next;+};++++#endif /* __C7108_AES_7108_H__ */diff -Nur linux-2.6.36.orig/crypto/ocf/c7108/Makefile linux-2.6.36/crypto/ocf/c7108/Makefile--- linux-2.6.36.orig/crypto/ocf/c7108/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/c7108/Makefile	2010-11-09 20:28:04.152495478 +0100@@ -0,0 +1,12 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_C7108) += aes-7108.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/Config.in linux-2.6.36/crypto/ocf/Config.in--- linux-2.6.36.orig/crypto/ocf/Config.in	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/Config.in	2010-11-09 20:28:04.191247583 +0100@@ -0,0 +1,36 @@+#############################################################################++mainmenu_option next_comment+comment 'OCF Configuration'+tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF+dep_mbool '  enable fips RNG checks (fips check on RNG data before use)' \+				CONFIG_OCF_FIPS $CONFIG_OCF_OCF+dep_mbool '  enable harvesting entropy for /dev/random' \+				CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF+dep_tristate '  cryptodev (user space support)' \+				CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF+dep_tristate '  cryptosoft (software crypto engine)' \+				CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF+dep_tristate '  safenet (HW crypto engine)' \+				CONFIG_OCF_SAFE $CONFIG_OCF_OCF+dep_tristate '  IXP4xx (HW crypto engine)' \+				CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF+dep_mbool    '  Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \+				CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX+dep_tristate '  hifn (HW crypto engine)' \+				CONFIG_OCF_HIFN $CONFIG_OCF_OCF+dep_tristate '  talitos (HW crypto engine)' \+				CONFIG_OCF_TALITOS $CONFIG_OCF_OCF+dep_tristate '  pasemi (HW crypto engine)' \+				CONFIG_OCF_PASEMI $CONFIG_OCF_OCF+dep_tristate '  ep80579 (HW crypto engine)' \+				CONFIG_OCF_EP80579 $CONFIG_OCF_OCF+dep_tristate '  Micronas c7108 (HW crypto engine)' \+				CONFIG_OCF_C7108 $CONFIG_OCF_OCF+dep_tristate '  ocfnull (does no crypto)' \+				CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF+dep_tristate '  ocf-bench (HW crypto in-kernel benchmark)' \+				CONFIG_OCF_BENCH $CONFIG_OCF_OCF+endmenu++#############################################################################diff -Nur linux-2.6.36.orig/crypto/ocf/criov.c linux-2.6.36/crypto/ocf/criov.c--- linux-2.6.36.orig/crypto/ocf/criov.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/criov.c	2010-11-09 20:28:04.232050075 +0100@@ -0,0 +1,215 @@+/*      $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $	*/++/*+ * Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ * The license and original author are listed below.+ *+ * Copyright (c) 1999 Theo de Raadt+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/slab.h>+#include <linux/uio.h>+#include <linux/skbuff.h>+#include <linux/kernel.h>+#include <linux/mm.h>+#include <asm/io.h>++#include <uio.h>+#include <cryptodev.h>++/*+ * This macro is only for avoiding code duplication, as we need to skip+ * given number of bytes in the same way in three functions below.+ */+#define	CUIO_SKIP()	do {						\+	KASSERT(off >= 0, ("%s: off %d < 0", __func__, off));		\+	KASSERT(len >= 0, ("%s: len %d < 0", __func__, len));		\+	while (off > 0) {						\+		KASSERT(iol >= 0, ("%s: empty in skip", __func__));	\+		if (off < iov->iov_len)					\+			break;						\+		off -= iov->iov_len;					\+		iol--;							\+		iov++;							\+	}								\+} while (0)++void+cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)+{+	struct iovec *iov = uio->uio_iov;+	int iol = uio->uio_iovcnt;+	unsigned count;++	CUIO_SKIP();+	while (len > 0) {+		KASSERT(iol >= 0, ("%s: empty", __func__));+		count = min((int)(iov->iov_len - off), len);+		memcpy(cp, ((caddr_t)iov->iov_base) + off, count);+		len -= count;+		cp += count;+		off = 0;+		iol--;+		iov++;+	}+}++void+cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)+{+	struct iovec *iov = uio->uio_iov;+	int iol = uio->uio_iovcnt;+	unsigned count;++	CUIO_SKIP();+	while (len > 0) {+		KASSERT(iol >= 0, ("%s: empty", __func__));+		count = min((int)(iov->iov_len - off), len);+		memcpy(((caddr_t)iov->iov_base) + off, cp, count);+		len -= count;+		cp += count;+		off = 0;+		iol--;+		iov++;+	}+}++/*+ * Return a pointer to iov/offset of location in iovec list.+ */+struct iovec *+cuio_getptr(struct uio *uio, int loc, int *off)+{+	struct iovec *iov = uio->uio_iov;+	int iol = uio->uio_iovcnt;++	while (loc >= 0) {+		/* Normal end of search */+		if (loc < iov->iov_len) {+	    		*off = loc;+	    		return (iov);+		}++		loc -= iov->iov_len;+		if (iol == 0) {+			if (loc == 0) {+				/* Point at the end of valid data */+				*off = iov->iov_len;+				return (iov);+			} else+				return (NULL);+		} else {+			iov++, iol--;+		}+    	}++	return (NULL);+}++EXPORT_SYMBOL(cuio_copyback);+EXPORT_SYMBOL(cuio_copydata);+EXPORT_SYMBOL(cuio_getptr);+++static void+skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)+{+	int i;+	if (offset < skb_headlen(skb)) {+		memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));+		len -= skb_headlen(skb);+		cp += skb_headlen(skb);+	}+	offset -= skb_headlen(skb);+	for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {+		if (offset < skb_shinfo(skb)->frags[i].size) {+			memcpy(page_address(skb_shinfo(skb)->frags[i].page) ++					skb_shinfo(skb)->frags[i].page_offset,+					cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));+			len -= skb_shinfo(skb)->frags[i].size;+			cp += skb_shinfo(skb)->frags[i].size;+		}+		offset -= skb_shinfo(skb)->frags[i].size;+	}+}++void+crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)+{++	if ((flags & CRYPTO_F_SKBUF) != 0)+		skb_copy_bits_back((struct sk_buff *)buf, off, in, size);+	else if ((flags & CRYPTO_F_IOV) != 0)+		cuio_copyback((struct uio *)buf, off, size, in);+	else+		bcopy(in, buf + off, size);+}++void+crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)+{++	if ((flags & CRYPTO_F_SKBUF) != 0)+		skb_copy_bits((struct sk_buff *)buf, off, out, size);+	else if ((flags & CRYPTO_F_IOV) != 0)+		cuio_copydata((struct uio *)buf, off, size, out);+	else+		bcopy(buf + off, out, size);+}++int+crypto_apply(int flags, caddr_t buf, int off, int len,+    int (*f)(void *, void *, u_int), void *arg)+{+#if 0+	int error;++	if ((flags & CRYPTO_F_SKBUF) != 0)+		error = XXXXXX((struct mbuf *)buf, off, len, f, arg);+	else if ((flags & CRYPTO_F_IOV) != 0)+		error = cuio_apply((struct uio *)buf, off, len, f, arg);+	else+		error = (*f)(arg, buf + off, len);+	return (error);+#else+	KASSERT(0, ("crypto_apply not implemented!\n"));+#endif+	return 0;+}++EXPORT_SYMBOL(crypto_copyback);+EXPORT_SYMBOL(crypto_copydata);+EXPORT_SYMBOL(crypto_apply);+diff -Nur linux-2.6.36.orig/crypto/ocf/crypto.c linux-2.6.36/crypto/ocf/crypto.c--- linux-2.6.36.orig/crypto/ocf/crypto.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/crypto.c	2010-11-09 20:28:04.272495385 +0100@@ -0,0 +1,1784 @@+/*-+ * Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ * The license and original author are listed below.+ *+ * Redistribution and use in source and binary forms, with or without+ * Copyright (c) 2002-2006 Sam Leffler.  All rights reserved.+ *+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */++#if 0+#include <sys/cdefs.h>+__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");+#endif++/*+ * Cryptographic Subsystem.+ *+ * This code is derived from the Openbsd Cryptographic Framework (OCF)+ * that has the copyright shown below.  Very little of the original+ * code remains.+ */+/*-+ * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)+ *+ * This code was written by Angelos D. Keromytis in Athens, Greece, in+ * February 2000. Network Security Technologies Inc. (NSTI) kindly+ * supported the development of this code.+ *+ * Copyright (c) 2000, 2001 Angelos D. Keromytis+ *+ * Permission to use, copy, and modify this software with or without fee+ * is hereby granted, provided that this entire notice is included in+ * all source code copies of any software which is or includes a copy or+ * modification of this software.+ *+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR+ * PURPOSE.+ *+__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");+ */+++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/wait.h>+#include <linux/sched.h>+#include <linux/spinlock.h>+#include <linux/version.h>+#include <cryptodev.h>++/*+ * keep track of whether or not we have been initialised, a big+ * issue if we are linked into the kernel and a driver gets started before+ * us+ */+static int crypto_initted = 0;++/*+ * Crypto drivers register themselves by allocating a slot in the+ * crypto_drivers table with crypto_get_driverid() and then registering+ * each algorithm they support with crypto_register() and crypto_kregister().+ */++/*+ * lock on driver table+ * we track its state as spin_is_locked does not do anything on non-SMP boxes+ */+static spinlock_t	crypto_drivers_lock;+static int			crypto_drivers_locked;		/* for non-SMP boxes */++#define	CRYPTO_DRIVER_LOCK() \+			({ \+				spin_lock_irqsave(&crypto_drivers_lock, d_flags); \+			 	crypto_drivers_locked = 1; \+				dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \+			 })+#define	CRYPTO_DRIVER_UNLOCK() \+			({ \+			 	dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \+			 	crypto_drivers_locked = 0; \+				spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \+			 })+#define	CRYPTO_DRIVER_ASSERT() \+			({ \+			 	if (!crypto_drivers_locked) { \+					dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \+			 	} \+			 })++/*+ * Crypto device/driver capabilities structure.+ *+ * Synchronization:+ * (d) - protected by CRYPTO_DRIVER_LOCK()+ * (q) - protected by CRYPTO_Q_LOCK()+ * Not tagged fields are read-only.+ */+struct cryptocap {+	device_t	cc_dev;			/* (d) device/driver */+	u_int32_t	cc_sessions;		/* (d) # of sessions */+	u_int32_t	cc_koperations;		/* (d) # os asym operations */+	/*+	 * Largest possible operator length (in bits) for each type of+	 * encryption algorithm. XXX not used+	 */+	u_int16_t	cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];+	u_int8_t	cc_alg[CRYPTO_ALGORITHM_MAX + 1];+	u_int8_t	cc_kalg[CRK_ALGORITHM_MAX + 1];++	int		cc_flags;		/* (d) flags */+#define CRYPTOCAP_F_CLEANUP	0x80000000	/* needs resource cleanup */+	int		cc_qblocked;		/* (q) symmetric q blocked */+	int		cc_kqblocked;		/* (q) asymmetric q blocked */++	int		cc_unqblocked;		/* (q) symmetric q blocked */+	int		cc_unkqblocked;		/* (q) asymmetric q blocked */+};+static struct cryptocap *crypto_drivers = NULL;+static int crypto_drivers_num = 0;++/*+ * There are two queues for crypto requests; one for symmetric (e.g.+ * cipher) operations and one for asymmetric (e.g. MOD)operations.+ * A single mutex is used to lock access to both queues.  We could+ * have one per-queue but having one simplifies handling of block/unblock+ * operations.+ */+static	int crp_sleep = 0;+static LIST_HEAD(crp_q);		/* request queues */+static LIST_HEAD(crp_kq);++static spinlock_t crypto_q_lock;++int crypto_all_qblocked = 0;  /* protect with Q_LOCK */+module_param(crypto_all_qblocked, int, 0444);+MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");++int crypto_all_kqblocked = 0; /* protect with Q_LOCK */+module_param(crypto_all_kqblocked, int, 0444);+MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");++#define	CRYPTO_Q_LOCK() \+			({ \+				spin_lock_irqsave(&crypto_q_lock, q_flags); \+			 	dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \+			 })+#define	CRYPTO_Q_UNLOCK() \+			({ \+			 	dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \+				spin_unlock_irqrestore(&crypto_q_lock, q_flags); \+			 })++/*+ * There are two queues for processing completed crypto requests; one+ * for the symmetric and one for the asymmetric ops.  We only need one+ * but have two to avoid type futzing (cryptop vs. cryptkop).  A single+ * mutex is used to lock access to both queues.  Note that this lock+ * must be separate from the lock on request queues to insure driver+ * callbacks don't generate lock order reversals.+ */+static LIST_HEAD(crp_ret_q);		/* callback queues */+static LIST_HEAD(crp_ret_kq);++static spinlock_t crypto_ret_q_lock;+#define	CRYPTO_RETQ_LOCK() \+			({ \+				spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \+				dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \+			 })+#define	CRYPTO_RETQ_UNLOCK() \+			({ \+			 	dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \+				spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \+			 })+#define	CRYPTO_RETQ_EMPTY()	(list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)+static kmem_cache_t *cryptop_zone;+static kmem_cache_t *cryptodesc_zone;+#else+static struct kmem_cache *cryptop_zone;+static struct kmem_cache *cryptodesc_zone;+#endif++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)+#include <linux/sched.h>+#define	kill_proc(p,s,v)	send_sig(s,find_task_by_vpid(p),0)+#endif++#define debug crypto_debug+int crypto_debug = 0;+module_param(crypto_debug, int, 0644);+MODULE_PARM_DESC(crypto_debug, "Enable debug");+EXPORT_SYMBOL(crypto_debug);++/*+ * Maximum number of outstanding crypto requests before we start+ * failing requests.  We need this to prevent DOS when too many+ * requests are arriving for us to keep up.  Otherwise we will+ * run the system out of memory.  Since crypto is slow,  we are+ * usually the bottleneck that needs to say, enough is enough.+ *+ * We cannot print errors when this condition occurs,  we are already too+ * slow,  printing anything will just kill us+ */++static int crypto_q_cnt = 0;+module_param(crypto_q_cnt, int, 0444);+MODULE_PARM_DESC(crypto_q_cnt,+		"Current number of outstanding crypto requests");++static int crypto_q_max = 1000;+module_param(crypto_q_max, int, 0644);+MODULE_PARM_DESC(crypto_q_max,+		"Maximum number of outstanding crypto requests");++#define bootverbose crypto_verbose+static int crypto_verbose = 0;+module_param(crypto_verbose, int, 0644);+MODULE_PARM_DESC(crypto_verbose,+		"Enable verbose crypto startup");++int	crypto_usercrypto = 1;	/* userland may do crypto reqs */+module_param(crypto_usercrypto, int, 0644);+MODULE_PARM_DESC(crypto_usercrypto,+	   "Enable/disable user-mode access to crypto support");++int	crypto_userasymcrypto = 1;	/* userland may do asym crypto reqs */+module_param(crypto_userasymcrypto, int, 0644);+MODULE_PARM_DESC(crypto_userasymcrypto,+	   "Enable/disable user-mode access to asymmetric crypto support");++int	crypto_devallowsoft = 0;	/* only use hardware crypto */+module_param(crypto_devallowsoft, int, 0644);+MODULE_PARM_DESC(crypto_devallowsoft,+	   "Enable/disable use of software crypto support");++/*+ * This parameter controls the maximum number of crypto operations to + * do consecutively in the crypto kernel thread before scheduling to allow + * other processes to run. Without it, it is possible to get into a + * situation where the crypto thread never allows any other processes to run.+ * Default to 1000 which should be less than one second.+ */+static int crypto_max_loopcount = 1000;+module_param(crypto_max_loopcount, int, 0644);+MODULE_PARM_DESC(crypto_max_loopcount,+	   "Maximum number of crypto ops to do before yielding to other processes");++static pid_t	cryptoproc = (pid_t) -1;+static struct	completion cryptoproc_exited;+static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);+static pid_t	cryptoretproc = (pid_t) -1;+static struct	completion cryptoretproc_exited;+static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);++static	int crypto_proc(void *arg);+static	int crypto_ret_proc(void *arg);+static	int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);+static	int crypto_kinvoke(struct cryptkop *krp, int flags);+static	void crypto_exit(void);+static  int crypto_init(void);++static	struct cryptostats cryptostats;++static struct cryptocap *+crypto_checkdriver(u_int32_t hid)+{+	if (crypto_drivers == NULL)+		return NULL;+	return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);+}++/*+ * Compare a driver's list of supported algorithms against another+ * list; return non-zero if all algorithms are supported.+ */+static int+driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)+{+	const struct cryptoini *cr;++	/* See if all the algorithms are supported. */+	for (cr = cri; cr; cr = cr->cri_next)+		if (cap->cc_alg[cr->cri_alg] == 0)+			return 0;+	return 1;+}++/*+ * Select a driver for a new session that supports the specified+ * algorithms and, optionally, is constrained according to the flags.+ * The algorithm we use here is pretty stupid; just use the+ * first driver that supports all the algorithms we need. If there+ * are multiple drivers we choose the driver with the fewest active+ * sessions.  We prefer hardware-backed drivers to software ones.+ *+ * XXX We need more smarts here (in real life too, but that's+ * XXX another story altogether).+ */+static struct cryptocap *+crypto_select_driver(const struct cryptoini *cri, int flags)+{+	struct cryptocap *cap, *best;+	int match, hid;++	CRYPTO_DRIVER_ASSERT();++	/*+	 * Look first for hardware crypto devices if permitted.+	 */+	if (flags & CRYPTOCAP_F_HARDWARE)+		match = CRYPTOCAP_F_HARDWARE;+	else+		match = CRYPTOCAP_F_SOFTWARE;+	best = NULL;+again:+	for (hid = 0; hid < crypto_drivers_num; hid++) {+		cap = &crypto_drivers[hid];+		/*+		 * If it's not initialized, is in the process of+		 * going away, or is not appropriate (hardware+		 * or software based on match), then skip.+		 */+		if (cap->cc_dev == NULL ||+		    (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||+		    (cap->cc_flags & match) == 0)+			continue;++		/* verify all the algorithms are supported. */+		if (driver_suitable(cap, cri)) {+			if (best == NULL ||+			    cap->cc_sessions < best->cc_sessions)+				best = cap;+		}+	}+	if (best != NULL)+		return best;+	if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {+		/* sort of an Algol 68-style for loop */+		match = CRYPTOCAP_F_SOFTWARE;+		goto again;+	}+	return best;+}++/*+ * Create a new session.  The crid argument specifies a crypto+ * driver to use or constraints on a driver to select (hardware+ * only, software only, either).  Whatever driver is selected+ * must be capable of the requested crypto algorithms.+ */+int+crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)+{+	struct cryptocap *cap;+	u_int32_t hid, lid;+	int err;+	unsigned long d_flags;++	CRYPTO_DRIVER_LOCK();+	if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {+		/*+		 * Use specified driver; verify it is capable.+		 */+		cap = crypto_checkdriver(crid);+		if (cap != NULL && !driver_suitable(cap, cri))+			cap = NULL;+	} else {+		/*+		 * No requested driver; select based on crid flags.+		 */+		cap = crypto_select_driver(cri, crid);+		/*+		 * if NULL then can't do everything in one session.+		 * XXX Fix this. We need to inject a "virtual" session+		 * XXX layer right about here.+		 */+	}+	if (cap != NULL) {+		/* Call the driver initialization routine. */+		hid = cap - crypto_drivers;+		lid = hid;		/* Pass the driver ID. */+		cap->cc_sessions++;+		CRYPTO_DRIVER_UNLOCK();+		err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);+		CRYPTO_DRIVER_LOCK();+		if (err == 0) {+			(*sid) = (cap->cc_flags & 0xff000000)+			       | (hid & 0x00ffffff);+			(*sid) <<= 32;+			(*sid) |= (lid & 0xffffffff);+		} else+			cap->cc_sessions--;+	} else+		err = EINVAL;+	CRYPTO_DRIVER_UNLOCK();+	return err;+}++static void+crypto_remove(struct cryptocap *cap)+{+	CRYPTO_DRIVER_ASSERT();+	if (cap->cc_sessions == 0 && cap->cc_koperations == 0)+		bzero(cap, sizeof(*cap));+}++/*+ * Delete an existing session (or a reserved session on an unregistered+ * driver).+ */+int+crypto_freesession(u_int64_t sid)+{+	struct cryptocap *cap;+	u_int32_t hid;+	int err = 0;+	unsigned long d_flags;++	dprintk("%s()\n", __FUNCTION__);+	CRYPTO_DRIVER_LOCK();++	if (crypto_drivers == NULL) {+		err = EINVAL;+		goto done;+	}++	/* Determine two IDs. */+	hid = CRYPTO_SESID2HID(sid);++	if (hid >= crypto_drivers_num) {+		dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);+		err = ENOENT;+		goto done;+	}+	cap = &crypto_drivers[hid];++	if (cap->cc_dev) {+		CRYPTO_DRIVER_UNLOCK();+		/* Call the driver cleanup routine, if available, unlocked. */+		err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);+		CRYPTO_DRIVER_LOCK();+	}++	if (cap->cc_sessions)+		cap->cc_sessions--;++	if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)+		crypto_remove(cap);++done:+	CRYPTO_DRIVER_UNLOCK();+	return err;+}++/*+ * Return an unused driver id.  Used by drivers prior to registering+ * support for the algorithms they handle.+ */+int32_t+crypto_get_driverid(device_t dev, int flags)+{+	struct cryptocap *newdrv;+	int i;+	unsigned long d_flags;++	if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {+		printf("%s: no flags specified when registering driver\n",+		    device_get_nameunit(dev));+		return -1;+	}++	CRYPTO_DRIVER_LOCK();++	for (i = 0; i < crypto_drivers_num; i++) {+		if (crypto_drivers[i].cc_dev == NULL &&+		    (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {+			break;+		}+	}++	/* Out of entries, allocate some more. */+	if (i == crypto_drivers_num) {+		/* Be careful about wrap-around. */+		if (2 * crypto_drivers_num <= crypto_drivers_num) {+			CRYPTO_DRIVER_UNLOCK();+			printk("crypto: driver count wraparound!\n");+			return -1;+		}++		newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),+				GFP_KERNEL);+		if (newdrv == NULL) {+			CRYPTO_DRIVER_UNLOCK();+			printk("crypto: no space to expand driver table!\n");+			return -1;+		}++		memcpy(newdrv, crypto_drivers,+				crypto_drivers_num * sizeof(struct cryptocap));+		memset(&newdrv[crypto_drivers_num], 0,+				crypto_drivers_num * sizeof(struct cryptocap));++		crypto_drivers_num *= 2;++		kfree(crypto_drivers);+		crypto_drivers = newdrv;+	}++	/* NB: state is zero'd on free */+	crypto_drivers[i].cc_sessions = 1;	/* Mark */+	crypto_drivers[i].cc_dev = dev;+	crypto_drivers[i].cc_flags = flags;+	if (bootverbose)+		printf("crypto: assign %s driver id %u, flags %u\n",+		    device_get_nameunit(dev), i, flags);++	CRYPTO_DRIVER_UNLOCK();++	return i;+}++/*+ * Lookup a driver by name.  We match against the full device+ * name and unit, and against just the name.  The latter gives+ * us a simple widlcarding by device name.  On success return the+ * driver/hardware identifier; otherwise return -1.+ */+int+crypto_find_driver(const char *match)+{+	int i, len = strlen(match);+	unsigned long d_flags;++	CRYPTO_DRIVER_LOCK();+	for (i = 0; i < crypto_drivers_num; i++) {+		device_t dev = crypto_drivers[i].cc_dev;+		if (dev == NULL ||+		    (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))+			continue;+		if (strncmp(match, device_get_nameunit(dev), len) == 0 ||+		    strncmp(match, device_get_name(dev), len) == 0)+			break;+	}+	CRYPTO_DRIVER_UNLOCK();+	return i < crypto_drivers_num ? i : -1;+}++/*+ * Return the device_t for the specified driver or NULL+ * if the driver identifier is invalid.+ */+device_t+crypto_find_device_byhid(int hid)+{+	struct cryptocap *cap = crypto_checkdriver(hid);+	return cap != NULL ? cap->cc_dev : NULL;+}++/*+ * Return the device/driver capabilities.+ */+int+crypto_getcaps(int hid)+{+	struct cryptocap *cap = crypto_checkdriver(hid);+	return cap != NULL ? cap->cc_flags : 0;+}++/*+ * Register support for a key-related algorithm.  This routine+ * is called once for each algorithm supported a driver.+ */+int+crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)+{+	struct cryptocap *cap;+	int err;+	unsigned long d_flags;++	dprintk("%s()\n", __FUNCTION__);+	CRYPTO_DRIVER_LOCK();++	cap = crypto_checkdriver(driverid);+	if (cap != NULL &&+	    (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {+		/*+		 * XXX Do some performance testing to determine placing.+		 * XXX We probably need an auxiliary data structure that+		 * XXX describes relative performances.+		 */++		cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;+		if (bootverbose)+			printf("crypto: %s registers key alg %u flags %u\n"+				, device_get_nameunit(cap->cc_dev)+				, kalg+				, flags+			);+		err = 0;+	} else+		err = EINVAL;++	CRYPTO_DRIVER_UNLOCK();+	return err;+}++/*+ * Register support for a non-key-related algorithm.  This routine+ * is called once for each such algorithm supported by a driver.+ */+int+crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,+    u_int32_t flags)+{+	struct cryptocap *cap;+	int err;+	unsigned long d_flags;++	dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,+			driverid, alg, maxoplen, flags);++	CRYPTO_DRIVER_LOCK();++	cap = crypto_checkdriver(driverid);+	/* NB: algorithms are in the range [1..max] */+	if (cap != NULL &&+	    (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {+		/*+		 * XXX Do some performance testing to determine placing.+		 * XXX We probably need an auxiliary data structure that+		 * XXX describes relative performances.+		 */++		cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;+		cap->cc_max_op_len[alg] = maxoplen;+		if (bootverbose)+			printf("crypto: %s registers alg %u flags %u maxoplen %u\n"+				, device_get_nameunit(cap->cc_dev)+				, alg+				, flags+				, maxoplen+			);+		cap->cc_sessions = 0;		/* Unmark */+		err = 0;+	} else+		err = EINVAL;++	CRYPTO_DRIVER_UNLOCK();+	return err;+}++static void+driver_finis(struct cryptocap *cap)+{+	u_int32_t ses, kops;++	CRYPTO_DRIVER_ASSERT();++	ses = cap->cc_sessions;+	kops = cap->cc_koperations;+	bzero(cap, sizeof(*cap));+	if (ses != 0 || kops != 0) {+		/*+		 * If there are pending sessions,+		 * just mark as invalid.+		 */+		cap->cc_flags |= CRYPTOCAP_F_CLEANUP;+		cap->cc_sessions = ses;+		cap->cc_koperations = kops;+	}+}++/*+ * Unregister a crypto driver. If there are pending sessions using it,+ * leave enough information around so that subsequent calls using those+ * sessions will correctly detect the driver has been unregistered and+ * reroute requests.+ */+int+crypto_unregister(u_int32_t driverid, int alg)+{+	struct cryptocap *cap;+	int i, err;+	unsigned long d_flags;++	dprintk("%s()\n", __FUNCTION__);+	CRYPTO_DRIVER_LOCK();++	cap = crypto_checkdriver(driverid);+	if (cap != NULL &&+	    (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&+	    cap->cc_alg[alg] != 0) {+		cap->cc_alg[alg] = 0;+		cap->cc_max_op_len[alg] = 0;++		/* Was this the last algorithm ? */+		for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)+			if (cap->cc_alg[i] != 0)+				break;++		if (i == CRYPTO_ALGORITHM_MAX + 1)+			driver_finis(cap);+		err = 0;+	} else+		err = EINVAL;+	CRYPTO_DRIVER_UNLOCK();+	return err;+}++/*+ * Unregister all algorithms associated with a crypto driver.+ * If there are pending sessions using it, leave enough information+ * around so that subsequent calls using those sessions will+ * correctly detect the driver has been unregistered and reroute+ * requests.+ */+int+crypto_unregister_all(u_int32_t driverid)+{+	struct cryptocap *cap;+	int err;+	unsigned long d_flags;++	dprintk("%s()\n", __FUNCTION__);+	CRYPTO_DRIVER_LOCK();+	cap = crypto_checkdriver(driverid);+	if (cap != NULL) {+		driver_finis(cap);+		err = 0;+	} else+		err = EINVAL;+	CRYPTO_DRIVER_UNLOCK();++	return err;+}++/*+ * Clear blockage on a driver.  The what parameter indicates whether+ * the driver is now ready for cryptop's and/or cryptokop's.+ */+int+crypto_unblock(u_int32_t driverid, int what)+{+	struct cryptocap *cap;+	int err;+	unsigned long q_flags;++	CRYPTO_Q_LOCK();+	cap = crypto_checkdriver(driverid);+	if (cap != NULL) {+		if (what & CRYPTO_SYMQ) {+			cap->cc_qblocked = 0;+			cap->cc_unqblocked = 0;+			crypto_all_qblocked = 0;+		}+		if (what & CRYPTO_ASYMQ) {+			cap->cc_kqblocked = 0;+			cap->cc_unkqblocked = 0;+			crypto_all_kqblocked = 0;+		}+		if (crp_sleep)+			wake_up_interruptible(&cryptoproc_wait);+		err = 0;+	} else+		err = EINVAL;+	CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock++	return err;+}++/*+ * Add a crypto request to a queue, to be processed by the kernel thread.+ */+int+crypto_dispatch(struct cryptop *crp)+{+	struct cryptocap *cap;+	int result = -1;+	unsigned long q_flags;++	dprintk("%s()\n", __FUNCTION__);++	cryptostats.cs_ops++;++	CRYPTO_Q_LOCK();+	if (crypto_q_cnt >= crypto_q_max) {+		CRYPTO_Q_UNLOCK();+		cryptostats.cs_drops++;+		return ENOMEM;+	}+	crypto_q_cnt++;++	/* make sure we are starting a fresh run on this crp. */+	crp->crp_flags &= ~CRYPTO_F_DONE;+	crp->crp_etype = 0;++	/*+	 * Caller marked the request to be processed immediately; dispatch+	 * it directly to the driver unless the driver is currently blocked.+	 */+	if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {+		int hid = CRYPTO_SESID2HID(crp->crp_sid);+		cap = crypto_checkdriver(hid);+		/* Driver cannot disappear when there is an active session. */+		KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));+		if (!cap->cc_qblocked) {+			crypto_all_qblocked = 0;+			crypto_drivers[hid].cc_unqblocked = 1;+			CRYPTO_Q_UNLOCK();+			result = crypto_invoke(cap, crp, 0);+			CRYPTO_Q_LOCK();+			if (result == ERESTART)+				if (crypto_drivers[hid].cc_unqblocked)+					crypto_drivers[hid].cc_qblocked = 1;+			crypto_drivers[hid].cc_unqblocked = 0;+		}+	}+	if (result == ERESTART) {+		/*+		 * The driver ran out of resources, mark the+		 * driver ``blocked'' for cryptop's and put+		 * the request back in the queue.  It would+		 * best to put the request back where we got+		 * it but that's hard so for now we put it+		 * at the front.  This should be ok; putting+		 * it at the end does not work.+		 */+		list_add(&crp->crp_next, &crp_q);+		cryptostats.cs_blocks++;+		result = 0;+	} else if (result == -1) {+		TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);+		result = 0;+	}+	if (crp_sleep)+		wake_up_interruptible(&cryptoproc_wait);+	CRYPTO_Q_UNLOCK();+	return result;+}++/*+ * Add an asymetric crypto request to a queue,+ * to be processed by the kernel thread.+ */+int+crypto_kdispatch(struct cryptkop *krp)+{+	int error;+	unsigned long q_flags;++	cryptostats.cs_kops++;++	error = crypto_kinvoke(krp, krp->krp_crid);+	if (error == ERESTART) {+		CRYPTO_Q_LOCK();+		TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);+		if (crp_sleep)+			wake_up_interruptible(&cryptoproc_wait);+		CRYPTO_Q_UNLOCK();+		error = 0;+	}+	return error;+}++/*+ * Verify a driver is suitable for the specified operation.+ */+static __inline int+kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)+{+	return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;+}++/*+ * Select a driver for an asym operation.  The driver must+ * support the necessary algorithm.  The caller can constrain+ * which device is selected with the flags parameter.  The+ * algorithm we use here is pretty stupid; just use the first+ * driver that supports the algorithms we need. If there are+ * multiple suitable drivers we choose the driver with the+ * fewest active operations.  We prefer hardware-backed+ * drivers to software ones when either may be used.+ */+static struct cryptocap *+crypto_select_kdriver(const struct cryptkop *krp, int flags)+{+	struct cryptocap *cap, *best, *blocked;+	int match, hid;++	CRYPTO_DRIVER_ASSERT();++	/*+	 * Look first for hardware crypto devices if permitted.+	 */+	if (flags & CRYPTOCAP_F_HARDWARE)+		match = CRYPTOCAP_F_HARDWARE;+	else+		match = CRYPTOCAP_F_SOFTWARE;+	best = NULL;+	blocked = NULL;+again:+	for (hid = 0; hid < crypto_drivers_num; hid++) {+		cap = &crypto_drivers[hid];+		/*+		 * If it's not initialized, is in the process of+		 * going away, or is not appropriate (hardware+		 * or software based on match), then skip.+		 */+		if (cap->cc_dev == NULL ||+		    (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||+		    (cap->cc_flags & match) == 0)+			continue;++		/* verify all the algorithms are supported. */+		if (kdriver_suitable(cap, krp)) {+			if (best == NULL ||+			    cap->cc_koperations < best->cc_koperations)+				best = cap;+		}+	}+	if (best != NULL)+		return best;+	if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {+		/* sort of an Algol 68-style for loop */+		match = CRYPTOCAP_F_SOFTWARE;+		goto again;+	}+	return best;+}++/*+ * Dispatch an assymetric crypto request.+ */+static int+crypto_kinvoke(struct cryptkop *krp, int crid)+{+	struct cryptocap *cap = NULL;+	int error;+	unsigned long d_flags;++	KASSERT(krp != NULL, ("%s: krp == NULL", __func__));+	KASSERT(krp->krp_callback != NULL,+	    ("%s: krp->crp_callback == NULL", __func__));++	CRYPTO_DRIVER_LOCK();+	if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {+		cap = crypto_checkdriver(crid);+		if (cap != NULL) {+			/*+			 * Driver present, it must support the necessary+			 * algorithm and, if s/w drivers are excluded,+			 * it must be registered as hardware-backed.+			 */+			if (!kdriver_suitable(cap, krp) ||+			    (!crypto_devallowsoft &&+			     (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))+				cap = NULL;+		}+	} else {+		/*+		 * No requested driver; select based on crid flags.+		 */+		if (!crypto_devallowsoft)	/* NB: disallow s/w drivers */+			crid &= ~CRYPTOCAP_F_SOFTWARE;+		cap = crypto_select_kdriver(krp, crid);+	}+	if (cap != NULL && !cap->cc_kqblocked) {+		krp->krp_hid = cap - crypto_drivers;+		cap->cc_koperations++;+		CRYPTO_DRIVER_UNLOCK();+		error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);+		CRYPTO_DRIVER_LOCK();+		if (error == ERESTART) {+			cap->cc_koperations--;+			CRYPTO_DRIVER_UNLOCK();+			return (error);+		}+		/* return the actual device used */+		krp->krp_crid = krp->krp_hid;+	} else {+		/*+		 * NB: cap is !NULL if device is blocked; in+		 *     that case return ERESTART so the operation+		 *     is resubmitted if possible.+		 */+		error = (cap == NULL) ? ENODEV : ERESTART;+	}+	CRYPTO_DRIVER_UNLOCK();++	if (error) {+		krp->krp_status = error;+		crypto_kdone(krp);+	}+	return 0;+}+++/*+ * Dispatch a crypto request to the appropriate crypto devices.+ */+static int+crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)+{+	KASSERT(crp != NULL, ("%s: crp == NULL", __func__));+	KASSERT(crp->crp_callback != NULL,+	    ("%s: crp->crp_callback == NULL", __func__));+	KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));++	dprintk("%s()\n", __FUNCTION__);++#ifdef CRYPTO_TIMING+	if (crypto_timing)+		crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);+#endif+	if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {+		struct cryptodesc *crd;+		u_int64_t nid;++		/*+		 * Driver has unregistered; migrate the session and return+		 * an error to the caller so they'll resubmit the op.+		 *+		 * XXX: What if there are more already queued requests for this+		 *      session?+		 */+		crypto_freesession(crp->crp_sid);++		for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)+			crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);++		/* XXX propagate flags from initial session? */+		if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),+		    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)+			crp->crp_sid = nid;++		crp->crp_etype = EAGAIN;+		crypto_done(crp);+		return 0;+	} else {+		/*+		 * Invoke the driver to process the request.+		 */+		return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);+	}+}++/*+ * Release a set of crypto descriptors.+ */+void+crypto_freereq(struct cryptop *crp)+{+	struct cryptodesc *crd;++	if (crp == NULL)+		return;++#ifdef DIAGNOSTIC+	{+		struct cryptop *crp2;+		unsigned long q_flags;++		CRYPTO_Q_LOCK();+		TAILQ_FOREACH(crp2, &crp_q, crp_next) {+			KASSERT(crp2 != crp,+			    ("Freeing cryptop from the crypto queue (%p).",+			    crp));+		}+		CRYPTO_Q_UNLOCK();+		CRYPTO_RETQ_LOCK();+		TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {+			KASSERT(crp2 != crp,+			    ("Freeing cryptop from the return queue (%p).",+			    crp));+		}+		CRYPTO_RETQ_UNLOCK();+	}+#endif++	while ((crd = crp->crp_desc) != NULL) {+		crp->crp_desc = crd->crd_next;+		kmem_cache_free(cryptodesc_zone, crd);+	}+	kmem_cache_free(cryptop_zone, crp);+}++/*+ * Acquire a set of crypto descriptors.+ */+struct cryptop *+crypto_getreq(int num)+{+	struct cryptodesc *crd;+	struct cryptop *crp;++	crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);+	if (crp != NULL) {+		memset(crp, 0, sizeof(*crp));+		INIT_LIST_HEAD(&crp->crp_next);+		init_waitqueue_head(&crp->crp_waitq);+		while (num--) {+			crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);+			if (crd == NULL) {+				crypto_freereq(crp);+				return NULL;+			}+			memset(crd, 0, sizeof(*crd));+			crd->crd_next = crp->crp_desc;+			crp->crp_desc = crd;+		}+	}+	return crp;+}++/*+ * Invoke the callback on behalf of the driver.+ */+void+crypto_done(struct cryptop *crp)+{+	unsigned long q_flags;++	dprintk("%s()\n", __FUNCTION__);+	if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {+		crp->crp_flags |= CRYPTO_F_DONE;+		CRYPTO_Q_LOCK();+		crypto_q_cnt--;+		CRYPTO_Q_UNLOCK();+	} else+		printk("crypto: crypto_done op already done, flags 0x%x",+				crp->crp_flags);+	if (crp->crp_etype != 0)+		cryptostats.cs_errs++;+	/*+	 * CBIMM means unconditionally do the callback immediately;+	 * CBIFSYNC means do the callback immediately only if the+	 * operation was done synchronously.  Both are used to avoid+	 * doing extraneous context switches; the latter is mostly+	 * used with the software crypto driver.+	 */+	if ((crp->crp_flags & CRYPTO_F_CBIMM) ||+	    ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&+	     (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {+		/*+		 * Do the callback directly.  This is ok when the+		 * callback routine does very little (e.g. the+		 * /dev/crypto callback method just does a wakeup).+		 */+		crp->crp_callback(crp);+	} else {+		unsigned long r_flags;+		/*+		 * Normal case; queue the callback for the thread.+		 */+		CRYPTO_RETQ_LOCK();+		if (CRYPTO_RETQ_EMPTY())+			wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */+		TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);+		CRYPTO_RETQ_UNLOCK();+	}+}++/*+ * Invoke the callback on behalf of the driver.+ */+void+crypto_kdone(struct cryptkop *krp)+{+	struct cryptocap *cap;+	unsigned long d_flags;++	if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)+		printk("crypto: crypto_kdone op already done, flags 0x%x",+				krp->krp_flags);+	krp->krp_flags |= CRYPTO_KF_DONE;+	if (krp->krp_status != 0)+		cryptostats.cs_kerrs++;++	CRYPTO_DRIVER_LOCK();+	/* XXX: What if driver is loaded in the meantime? */+	if (krp->krp_hid < crypto_drivers_num) {+		cap = &crypto_drivers[krp->krp_hid];+		cap->cc_koperations--;+		KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));+		if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)+			crypto_remove(cap);+	}+	CRYPTO_DRIVER_UNLOCK();++	/*+	 * CBIMM means unconditionally do the callback immediately;+	 * This is used to avoid doing extraneous context switches+	 */+	if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {+		/*+		 * Do the callback directly.  This is ok when the+		 * callback routine does very little (e.g. the+		 * /dev/crypto callback method just does a wakeup).+		 */+		krp->krp_callback(krp);+	} else {+		unsigned long r_flags;+		/*+		 * Normal case; queue the callback for the thread.+		 */+		CRYPTO_RETQ_LOCK();+		if (CRYPTO_RETQ_EMPTY())+			wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */+		TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);+		CRYPTO_RETQ_UNLOCK();+	}+}++int+crypto_getfeat(int *featp)+{+	int hid, kalg, feat = 0;+	unsigned long d_flags;++	CRYPTO_DRIVER_LOCK();+	for (hid = 0; hid < crypto_drivers_num; hid++) {+		const struct cryptocap *cap = &crypto_drivers[hid];++		if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&+		    !crypto_devallowsoft) {+			continue;+		}+		for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)+			if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)+				feat |=  1 << kalg;+	}+	CRYPTO_DRIVER_UNLOCK();+	*featp = feat;+	return (0);+}++/*+ * Crypto thread, dispatches crypto requests.+ */+static int+crypto_proc(void *arg)+{+	struct cryptop *crp, *submit;+	struct cryptkop *krp, *krpp;+	struct cryptocap *cap;+	u_int32_t hid;+	int result, hint;+	unsigned long q_flags;+	int loopcount = 0;++	ocf_daemonize("crypto");++	CRYPTO_Q_LOCK();+	for (;;) {+		/*+		 * we need to make sure we don't get into a busy loop with nothing+		 * to do,  the two crypto_all_*blocked vars help us find out when+		 * we are all full and can do nothing on any driver or Q.  If so we+		 * wait for an unblock.+		 */+		crypto_all_qblocked  = !list_empty(&crp_q);++		/*+		 * Find the first element in the queue that can be+		 * processed and look-ahead to see if multiple ops+		 * are ready for the same driver.+		 */+		submit = NULL;+		hint = 0;+		list_for_each_entry(crp, &crp_q, crp_next) {+			hid = CRYPTO_SESID2HID(crp->crp_sid);+			cap = crypto_checkdriver(hid);+			/*+			 * Driver cannot disappear when there is an active+			 * session.+			 */+			KASSERT(cap != NULL, ("%s:%u Driver disappeared.",+			    __func__, __LINE__));+			if (cap == NULL || cap->cc_dev == NULL) {+				/* Op needs to be migrated, process it. */+				if (submit == NULL)+					submit = crp;+				break;+			}+			if (!cap->cc_qblocked) {+				if (submit != NULL) {+					/*+					 * We stop on finding another op,+					 * regardless whether its for the same+					 * driver or not.  We could keep+					 * searching the queue but it might be+					 * better to just use a per-driver+					 * queue instead.+					 */+					if (CRYPTO_SESID2HID(submit->crp_sid) == hid)+						hint = CRYPTO_HINT_MORE;+					break;+				} else {+					submit = crp;+					if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)+						break;+					/* keep scanning for more are q'd */+				}+			}+		}+		if (submit != NULL) {+			hid = CRYPTO_SESID2HID(submit->crp_sid);+			crypto_all_qblocked = 0;+			list_del(&submit->crp_next);+			crypto_drivers[hid].cc_unqblocked = 1;+			cap = crypto_checkdriver(hid);+			CRYPTO_Q_UNLOCK();+			KASSERT(cap != NULL, ("%s:%u Driver disappeared.",+			    __func__, __LINE__));+			result = crypto_invoke(cap, submit, hint);+			CRYPTO_Q_LOCK();+			if (result == ERESTART) {+				/*+				 * The driver ran out of resources, mark the+				 * driver ``blocked'' for cryptop's and put+				 * the request back in the queue.  It would+				 * best to put the request back where we got+				 * it but that's hard so for now we put it+				 * at the front.  This should be ok; putting+				 * it at the end does not work.+				 */+				/* XXX validate sid again? */+				list_add(&submit->crp_next, &crp_q);+				cryptostats.cs_blocks++;+				if (crypto_drivers[hid].cc_unqblocked)+					crypto_drivers[hid].cc_qblocked=0;+				crypto_drivers[hid].cc_unqblocked=0;+			}+			crypto_drivers[hid].cc_unqblocked = 0;+		}++		crypto_all_kqblocked = !list_empty(&crp_kq);++		/* As above, but for key ops */+		krp = NULL;+		list_for_each_entry(krpp, &crp_kq, krp_next) {+			cap = crypto_checkdriver(krpp->krp_hid);+			if (cap == NULL || cap->cc_dev == NULL) {+				/*+				 * Operation needs to be migrated, invalidate+				 * the assigned device so it will reselect a+				 * new one below.  Propagate the original+				 * crid selection flags if supplied.+				 */+				krp->krp_hid = krp->krp_crid &+				    (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);+				if (krp->krp_hid == 0)+					krp->krp_hid =+				    CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;+				break;+			}+			if (!cap->cc_kqblocked) {+				krp = krpp;+				break;+			}+		}+		if (krp != NULL) {+			crypto_all_kqblocked = 0;+			list_del(&krp->krp_next);+			crypto_drivers[krp->krp_hid].cc_kqblocked = 1;+			CRYPTO_Q_UNLOCK();+			result = crypto_kinvoke(krp, krp->krp_hid);+			CRYPTO_Q_LOCK();+			if (result == ERESTART) {+				/*+				 * The driver ran out of resources, mark the+				 * driver ``blocked'' for cryptkop's and put+				 * the request back in the queue.  It would+				 * best to put the request back where we got+				 * it but that's hard so for now we put it+				 * at the front.  This should be ok; putting+				 * it at the end does not work.+				 */+				/* XXX validate sid again? */+				list_add(&krp->krp_next, &crp_kq);+				cryptostats.cs_kblocks++;+			} else+				crypto_drivers[krp->krp_hid].cc_kqblocked = 0;+		}++		if (submit == NULL && krp == NULL) {+			/*+			 * Nothing more to be processed.  Sleep until we're+			 * woken because there are more ops to process.+			 * This happens either by submission or by a driver+			 * becoming unblocked and notifying us through+			 * crypto_unblock.  Note that when we wakeup we+			 * start processing each queue again from the+			 * front. It's not clear that it's important to+			 * preserve this ordering since ops may finish+			 * out of order if dispatched to different devices+			 * and some become blocked while others do not.+			 */+			dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",+					__FUNCTION__,+					list_empty(&crp_q), crypto_all_qblocked,+					list_empty(&crp_kq), crypto_all_kqblocked);+			loopcount = 0;+			CRYPTO_Q_UNLOCK();+			crp_sleep = 1;+			wait_event_interruptible(cryptoproc_wait,+					!(list_empty(&crp_q) || crypto_all_qblocked) ||+					!(list_empty(&crp_kq) || crypto_all_kqblocked) ||+					cryptoproc == (pid_t) -1);+			crp_sleep = 0;+			if (signal_pending (current)) {+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+				spin_lock_irq(¤t->sigmask_lock);+#endif+				flush_signals(current);+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+				spin_unlock_irq(¤t->sigmask_lock);+#endif+			}+			CRYPTO_Q_LOCK();+			dprintk("%s - awake\n", __FUNCTION__);+			if (cryptoproc == (pid_t) -1)+				break;+			cryptostats.cs_intrs++;+		} else if (loopcount > crypto_max_loopcount) {+			/*+			 * Give other processes a chance to run if we've +			 * been using the CPU exclusively for a while.+			 */+			loopcount = 0;+			schedule();+		}+		loopcount++;+	}+	CRYPTO_Q_UNLOCK();+	complete_and_exit(&cryptoproc_exited, 0);+}++/*+ * Crypto returns thread, does callbacks for processed crypto requests.+ * Callbacks are done here, rather than in the crypto drivers, because+ * callbacks typically are expensive and would slow interrupt handling.+ */+static int+crypto_ret_proc(void *arg)+{+	struct cryptop *crpt;+	struct cryptkop *krpt;+	unsigned long  r_flags;++	ocf_daemonize("crypto_ret");++	CRYPTO_RETQ_LOCK();+	for (;;) {+		/* Harvest return q's for completed ops */+		crpt = NULL;+		if (!list_empty(&crp_ret_q))+			crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);+		if (crpt != NULL)+			list_del(&crpt->crp_next);++		krpt = NULL;+		if (!list_empty(&crp_ret_kq))+			krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);+		if (krpt != NULL)+			list_del(&krpt->krp_next);++		if (crpt != NULL || krpt != NULL) {+			CRYPTO_RETQ_UNLOCK();+			/*+			 * Run callbacks unlocked.+			 */+			if (crpt != NULL)+				crpt->crp_callback(crpt);+			if (krpt != NULL)+				krpt->krp_callback(krpt);+			CRYPTO_RETQ_LOCK();+		} else {+			/*+			 * Nothing more to be processed.  Sleep until we're+			 * woken because there are more returns to process.+			 */+			dprintk("%s - sleeping\n", __FUNCTION__);+			CRYPTO_RETQ_UNLOCK();+			wait_event_interruptible(cryptoretproc_wait,+					cryptoretproc == (pid_t) -1 ||+					!list_empty(&crp_ret_q) ||+					!list_empty(&crp_ret_kq));+			if (signal_pending (current)) {+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+				spin_lock_irq(¤t->sigmask_lock);+#endif+				flush_signals(current);+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+				spin_unlock_irq(¤t->sigmask_lock);+#endif+			}+			CRYPTO_RETQ_LOCK();+			dprintk("%s - awake\n", __FUNCTION__);+			if (cryptoretproc == (pid_t) -1) {+				dprintk("%s - EXITING!\n", __FUNCTION__);+				break;+			}+			cryptostats.cs_rets++;+		}+	}+	CRYPTO_RETQ_UNLOCK();+	complete_and_exit(&cryptoretproc_exited, 0);+}+++#if 0 /* should put this into /proc or something */+static void+db_show_drivers(void)+{+	int hid;++	db_printf("%12s %4s %4s %8s %2s %2s\n"+		, "Device"+		, "Ses"+		, "Kops"+		, "Flags"+		, "QB"+		, "KB"+	);+	for (hid = 0; hid < crypto_drivers_num; hid++) {+		const struct cryptocap *cap = &crypto_drivers[hid];+		if (cap->cc_dev == NULL)+			continue;+		db_printf("%-12s %4u %4u %08x %2u %2u\n"+		    , device_get_nameunit(cap->cc_dev)+		    , cap->cc_sessions+		    , cap->cc_koperations+		    , cap->cc_flags+		    , cap->cc_qblocked+		    , cap->cc_kqblocked+		);+	}+}++DB_SHOW_COMMAND(crypto, db_show_crypto)+{+	struct cryptop *crp;++	db_show_drivers();+	db_printf("\n");++	db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",+	    "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",+	    "Desc", "Callback");+	TAILQ_FOREACH(crp, &crp_q, crp_next) {+		db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"+		    , (int) CRYPTO_SESID2HID(crp->crp_sid)+		    , (int) CRYPTO_SESID2CAPS(crp->crp_sid)+		    , crp->crp_ilen, crp->crp_olen+		    , crp->crp_etype+		    , crp->crp_flags+		    , crp->crp_desc+		    , crp->crp_callback+		);+	}+	if (!TAILQ_EMPTY(&crp_ret_q)) {+		db_printf("\n%4s %4s %4s %8s\n",+		    "HID", "Etype", "Flags", "Callback");+		TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {+			db_printf("%4u %4u %04x %8p\n"+			    , (int) CRYPTO_SESID2HID(crp->crp_sid)+			    , crp->crp_etype+			    , crp->crp_flags+			    , crp->crp_callback+			);+		}+	}+}++DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)+{+	struct cryptkop *krp;++	db_show_drivers();+	db_printf("\n");++	db_printf("%4s %5s %4s %4s %8s %4s %8s\n",+	    "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");+	TAILQ_FOREACH(krp, &crp_kq, krp_next) {+		db_printf("%4u %5u %4u %4u %08x %4u %8p\n"+		    , krp->krp_op+		    , krp->krp_status+		    , krp->krp_iparams, krp->krp_oparams+		    , krp->krp_crid, krp->krp_hid+		    , krp->krp_callback+		);+	}+	if (!TAILQ_EMPTY(&crp_ret_q)) {+		db_printf("%4s %5s %8s %4s %8s\n",+		    "Op", "Status", "CRID", "HID", "Callback");+		TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {+			db_printf("%4u %5u %08x %4u %8p\n"+			    , krp->krp_op+			    , krp->krp_status+			    , krp->krp_crid, krp->krp_hid+			    , krp->krp_callback+			);+		}+	}+}+#endif+++static int+crypto_init(void)+{+	int error;++	dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);++	if (crypto_initted)+		return 0;+	crypto_initted = 1;++	spin_lock_init(&crypto_drivers_lock);+	spin_lock_init(&crypto_q_lock);+	spin_lock_init(&crypto_ret_q_lock);++	cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),+				       0, SLAB_HWCACHE_ALIGN, NULL+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)+				       , NULL+#endif+					);++	cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),+				       0, SLAB_HWCACHE_ALIGN, NULL+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)+				       , NULL+#endif+					);++	if (cryptodesc_zone == NULL || cryptop_zone == NULL) {+		printk("crypto: crypto_init cannot setup crypto zones\n");+		error = ENOMEM;+		goto bad;+	}++	crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;+	crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),+			GFP_KERNEL);+	if (crypto_drivers == NULL) {+		printk("crypto: crypto_init cannot setup crypto drivers\n");+		error = ENOMEM;+		goto bad;+	}++	memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));++	init_completion(&cryptoproc_exited);+	init_completion(&cryptoretproc_exited);++	cryptoproc = 0; /* to avoid race condition where proc runs first */+	cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);+	if (cryptoproc < 0) {+		error = cryptoproc;+		printk("crypto: crypto_init cannot start crypto thread; error %d",+			error);+		goto bad;+	}++	cryptoretproc = 0; /* to avoid race condition where proc runs first */+	cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);+	if (cryptoretproc < 0) {+		error = cryptoretproc;+		printk("crypto: crypto_init cannot start cryptoret thread; error %d",+				error);+		goto bad;+	}++	return 0;+bad:+	crypto_exit();+	return error;+}+++static void+crypto_exit(void)+{+	pid_t p;+	unsigned long d_flags;++	dprintk("%s()\n", __FUNCTION__);++	/*+	 * Terminate any crypto threads.+	 */++	CRYPTO_DRIVER_LOCK();+	p = cryptoproc;+	cryptoproc = (pid_t) -1;+	kill_proc(p, SIGTERM, 1);+	wake_up_interruptible(&cryptoproc_wait);+	CRYPTO_DRIVER_UNLOCK();++	wait_for_completion(&cryptoproc_exited);++	CRYPTO_DRIVER_LOCK();+	p = cryptoretproc;+	cryptoretproc = (pid_t) -1;+	kill_proc(p, SIGTERM, 1);+	wake_up_interruptible(&cryptoretproc_wait);+	CRYPTO_DRIVER_UNLOCK();++	wait_for_completion(&cryptoretproc_exited);++	/* XXX flush queues??? */++	/* +	 * Reclaim dynamically allocated resources.+	 */+	if (crypto_drivers != NULL)+		kfree(crypto_drivers);++	if (cryptodesc_zone != NULL)+		kmem_cache_destroy(cryptodesc_zone);+	if (cryptop_zone != NULL)+		kmem_cache_destroy(cryptop_zone);+}+++EXPORT_SYMBOL(crypto_newsession);+EXPORT_SYMBOL(crypto_freesession);+EXPORT_SYMBOL(crypto_get_driverid);+EXPORT_SYMBOL(crypto_kregister);+EXPORT_SYMBOL(crypto_register);+EXPORT_SYMBOL(crypto_unregister);+EXPORT_SYMBOL(crypto_unregister_all);+EXPORT_SYMBOL(crypto_unblock);+EXPORT_SYMBOL(crypto_dispatch);+EXPORT_SYMBOL(crypto_kdispatch);+EXPORT_SYMBOL(crypto_freereq);+EXPORT_SYMBOL(crypto_getreq);+EXPORT_SYMBOL(crypto_done);+EXPORT_SYMBOL(crypto_kdone);+EXPORT_SYMBOL(crypto_getfeat);+EXPORT_SYMBOL(crypto_userasymcrypto);+EXPORT_SYMBOL(crypto_getcaps);+EXPORT_SYMBOL(crypto_find_driver);+EXPORT_SYMBOL(crypto_find_device_byhid);++module_init(crypto_init);+module_exit(crypto_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/cavium_crypto.c linux-2.6.36/crypto/ocf/cryptocteon/cavium_crypto.c--- linux-2.6.36.orig/crypto/ocf/cryptocteon/cavium_crypto.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/cryptocteon/cavium_crypto.c	2010-11-09 20:28:04.311245450 +0100@@ -0,0 +1,2283 @@+/*+ * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>+ *+ * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights+ * reserved.+ * + * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions are met:+ * 1. Redistributions of source code must retain the above copyright notice,+ * this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright notice,+ * this list of conditions and the following disclaimer in the documentation+ * and/or other materials provided with the distribution.+ * 3. All advertising materials mentioning features or use of this software+ * must display the following acknowledgement:+ * This product includes software developed by Cavium Networks+ * 4. Cavium Networks' name may not be used to endorse or promote products+ * derived from this software without specific prior written permission.+ * + * This Software, including technical data, may be subject to U.S. export+ * control laws, including the U.S. Export Administration Act and its+ * associated regulations, and may be subject to export or import regulations+ * in other countries. You warrant that You will comply strictly in all+ * respects with all such regulations and acknowledge that you have the+ * responsibility to obtain licenses to export, re-export or import the+ * Software.+ * + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND+ * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,+ * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE+ * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR+ * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM+ * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,+ * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF+ * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR+ * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR+ * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.+*/+/****************************************************************************/++#include <linux/scatterlist.h>+#include <asm/octeon/octeon.h>+#include "octeon-asm.h"++/****************************************************************************/++extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *);+extern void octeon_crypto_disable(struct octeon_cop2_state *, unsigned long);++#define SG_INIT(s, p, i, l) \+	{ \+	    (i) = 0; \+	    (l) = (s)[0].length; \+	    (p) = (typeof(p)) sg_virt((s)); \+		CVMX_PREFETCH0((p)); \+	}++#define SG_CONSUME(s, p, i, l) \+	{ \+		(p)++; \+		(l) -= sizeof(*(p)); \+		if ((l) < 0) { \+			dprintk("%s, %d: l = %d\n", __FILE__, __LINE__, l); \+		} else if ((l) == 0) { \+		    (i)++; \+		    (l) = (s)[0].length; \+		    (p) = (typeof(p)) sg_virt(s); \+			CVMX_PREFETCH0((p)); \+		} \+	}++#define ESP_HEADER_LENGTH     8+#define DES_CBC_IV_LENGTH     8+#define AES_CBC_IV_LENGTH     16+#define ESP_HMAC_LEN          12++#define ESP_HEADER_LENGTH 8+#define DES_CBC_IV_LENGTH 8++/****************************************************************************/++#define CVM_LOAD_SHA_UNIT(dat, next)  { \+   if (next == 0) {                     \+      next = 1;                         \+      CVMX_MT_HSH_DAT (dat, 0);         \+   } else if (next == 1) {              \+      next = 2;                         \+      CVMX_MT_HSH_DAT (dat, 1);         \+   } else if (next == 2) {              \+      next = 3;                    \+      CVMX_MT_HSH_DAT (dat, 2);         \+   } else if (next == 3) {              \+      next = 4;                         \+      CVMX_MT_HSH_DAT (dat, 3);         \+   } else if (next == 4) {              \+      next = 5;                           \+      CVMX_MT_HSH_DAT (dat, 4);         \+   } else if (next == 5) {              \+      next = 6;                         \+      CVMX_MT_HSH_DAT (dat, 5);         \+   } else if (next == 6) {              \+      next = 7;                         \+      CVMX_MT_HSH_DAT (dat, 6);         \+   } else {                             \+     CVMX_MT_HSH_STARTSHA (dat);        \+     next = 0;                          \+   }                                    \+}++#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next)  { \+   if (next == 0) {                      \+      CVMX_MT_HSH_DAT (dat1, 0);         \+      CVMX_MT_HSH_DAT (dat2, 1);         \+      next = 2;                          \+   } else if (next == 1) {               \+      CVMX_MT_HSH_DAT (dat1, 1);         \+      CVMX_MT_HSH_DAT (dat2, 2);         \+      next = 3;                          \+   } else if (next == 2) {               \+      CVMX_MT_HSH_DAT (dat1, 2);         \+      CVMX_MT_HSH_DAT (dat2, 3);         \+      next = 4;                          \+   } else if (next == 3) {               \+      CVMX_MT_HSH_DAT (dat1, 3);         \+      CVMX_MT_HSH_DAT (dat2, 4);         \+      next = 5;                          \+   } else if (next == 4) {               \+      CVMX_MT_HSH_DAT (dat1, 4);         \+      CVMX_MT_HSH_DAT (dat2, 5);         \+      next = 6;                          \+   } else if (next == 5) {               \+      CVMX_MT_HSH_DAT (dat1, 5);         \+      CVMX_MT_HSH_DAT (dat2, 6);         \+      next = 7;                          \+   } else if (next == 6) {               \+      CVMX_MT_HSH_DAT (dat1, 6);         \+      CVMX_MT_HSH_STARTSHA (dat2);       \+      next = 0;                          \+   } else {                              \+     CVMX_MT_HSH_STARTSHA (dat1);        \+     CVMX_MT_HSH_DAT (dat2, 0);          \+     next = 1;                           \+   }                                     \+}++/****************************************************************************/++#define CVM_LOAD_MD5_UNIT(dat, next)  { \+   if (next == 0) {                     \+      next = 1;                         \+      CVMX_MT_HSH_DAT (dat, 0);         \+   } else if (next == 1) {              \+      next = 2;                         \+      CVMX_MT_HSH_DAT (dat, 1);         \+   } else if (next == 2) {              \+      next = 3;                    \+      CVMX_MT_HSH_DAT (dat, 2);         \+   } else if (next == 3) {              \+      next = 4;                         \+      CVMX_MT_HSH_DAT (dat, 3);         \+   } else if (next == 4) {              \+      next = 5;                           \+      CVMX_MT_HSH_DAT (dat, 4);         \+   } else if (next == 5) {              \+      next = 6;                         \+      CVMX_MT_HSH_DAT (dat, 5);         \+   } else if (next == 6) {              \+      next = 7;                         \+      CVMX_MT_HSH_DAT (dat, 6);         \+   } else {                             \+     CVMX_MT_HSH_STARTMD5 (dat);        \+     next = 0;                          \+   }                                    \+}++#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next)  { \+   if (next == 0) {                      \+      CVMX_MT_HSH_DAT (dat1, 0);         \+      CVMX_MT_HSH_DAT (dat2, 1);         \+      next = 2;                          \+   } else if (next == 1) {               \+      CVMX_MT_HSH_DAT (dat1, 1);         \+      CVMX_MT_HSH_DAT (dat2, 2);         \+      next = 3;                          \+   } else if (next == 2) {               \+      CVMX_MT_HSH_DAT (dat1, 2);         \+      CVMX_MT_HSH_DAT (dat2, 3);         \+      next = 4;                          \+   } else if (next == 3) {               \+      CVMX_MT_HSH_DAT (dat1, 3);         \+      CVMX_MT_HSH_DAT (dat2, 4);         \+      next = 5;                          \+   } else if (next == 4) {               \+      CVMX_MT_HSH_DAT (dat1, 4);         \+      CVMX_MT_HSH_DAT (dat2, 5);         \+      next = 6;                          \+   } else if (next == 5) {               \+      CVMX_MT_HSH_DAT (dat1, 5);         \+      CVMX_MT_HSH_DAT (dat2, 6);         \+      next = 7;                          \+   } else if (next == 6) {               \+      CVMX_MT_HSH_DAT (dat1, 6);         \+      CVMX_MT_HSH_STARTMD5 (dat2);       \+      next = 0;                          \+   } else {                              \+     CVMX_MT_HSH_STARTMD5 (dat1);        \+     CVMX_MT_HSH_DAT (dat2, 0);          \+     next = 1;                           \+   }                                     \+}++/****************************************************************************/++static inline uint64_t+swap64(uint64_t a)+{+    return ((a >> 56) |+       (((a >> 48) & 0xfful) << 8) |+       (((a >> 40) & 0xfful) << 16) |+       (((a >> 32) & 0xfful) << 24) |+       (((a >> 24) & 0xfful) << 32) |+       (((a >> 16) & 0xfful) << 40) |+       (((a >> 8) & 0xfful) << 48) | (((a >> 0) & 0xfful) << 56));+}++/****************************************************************************/++void+octo_calc_hash(__u8 auth, unsigned char *key, uint64_t *inner, uint64_t *outer)+{+    uint8_t hash_key[64];+    uint64_t *key1;+    register uint64_t xor1 = 0x3636363636363636ULL;+    register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    memset(hash_key, 0, sizeof(hash_key));+    memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));+    key1 = (uint64_t *) hash_key;+    flags = octeon_crypto_enable(&state);+    if (auth) {+       CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);+       CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);+       CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);+    } else {+       CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);+       CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);+    }++    CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);+    key1++;+    if (auth)+	CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));+    else+	CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));++    CVMX_MF_HSH_IV(inner[0], 0);+    CVMX_MF_HSH_IV(inner[1], 1);+    if (auth) {+	inner[2] = 0;+	CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);+    }++    memset(hash_key, 0, sizeof(hash_key));+    memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));+    key1 = (uint64_t *) hash_key;+    if (auth) {+      CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);+      CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);+      CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);+    } else {+      CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);+      CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);+    }++    CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);+    key1++;+    CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);+    key1++;+    if (auth)+       CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));+    else +       CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));++    CVMX_MF_HSH_IV(outer[0], 0);+    CVMX_MF_HSH_IV(outer[1], 1);+    if (auth) {+      outer[2] = 0;+      CVMX_MF_HSH_IV(outer[2], 2);+    }+    octeon_crypto_disable(&state, flags);+    return;+}++/****************************************************************************/+/* DES functions */++int+octo_des_cbc_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    uint64_t *data;+    int data_i, data_l;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load 3DES Key */+    CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    if (od->octo_encklen == 24) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+    } else if (od->octo_encklen == 8) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }++    CVMX_MT_3DES_IV(* (uint64_t *) ivp);++    while (crypt_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_off -= 8;+    }++    while (crypt_len > 0) {+	CVMX_MT_3DES_ENC_CBC(*data);+	CVMX_MF_3DES_RESULT(*data);+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_len -= 8;+    }++    octeon_crypto_disable(&state, flags);+    return 0;+}+++int+octo_des_cbc_decrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    uint64_t *data;+    int data_i, data_l;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load 3DES Key */+    CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    if (od->octo_encklen == 24) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+    } else if (od->octo_encklen == 8) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }++    CVMX_MT_3DES_IV(* (uint64_t *) ivp);++    while (crypt_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_off -= 8;+    }++    while (crypt_len > 0) {+	CVMX_MT_3DES_DEC_CBC(*data);+	CVMX_MF_3DES_RESULT(*data);+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_len -= 8;+    }++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* AES functions */++int+octo_aes_cbc_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    uint64_t *data, *pdata;+    int data_i, data_l;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load AES Key */+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);++    if (od->octo_encklen == 16) {+	CVMX_MT_AES_KEY(0x0, 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 24) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 32) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }+    CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);++    CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);+    CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);++    while (crypt_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_off -= 8;+    }++    while (crypt_len > 0) {+	pdata = data;+	CVMX_MT_AES_ENC_CBC0(*data);+	SG_CONSUME(sg, data, data_i, data_l);+	CVMX_MT_AES_ENC_CBC1(*data);+	CVMX_MF_AES_RESULT(*pdata, 0);+	CVMX_MF_AES_RESULT(*data, 1);+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_len -= 16;+    }++    octeon_crypto_disable(&state, flags);+    return 0;+}+++int+octo_aes_cbc_decrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    uint64_t *data, *pdata;+    int data_i, data_l;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load AES Key */+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);++    if (od->octo_encklen == 16) {+	CVMX_MT_AES_KEY(0x0, 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 24) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 32) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }+    CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);++    CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);+    CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);++    while (crypt_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_off -= 8;+    }++    while (crypt_len > 0) {+	pdata = data;+	CVMX_MT_AES_DEC_CBC0(*data);+	SG_CONSUME(sg, data, data_i, data_l);+	CVMX_MT_AES_DEC_CBC1(*data);+	CVMX_MF_AES_RESULT(*pdata, 0);+	CVMX_MF_AES_RESULT(*data, 1);+	SG_CONSUME(sg, data, data_i, data_l);+	crypt_len -= 16;+    }++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* MD5 */++int+octo_null_md5_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    uint64_t *data;+    uint64_t tmp1, tmp2;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 ||+	    (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data, data_i, data_l);++    flags = octeon_crypto_enable(&state);++    /* Load MD5 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);++    while (auth_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	auth_off -= 8;+    }++    while (auth_len > 0) {+	CVM_LOAD_MD5_UNIT(*data, next);+	auth_len -= 8;+	SG_CONSUME(sg, data, data_i, data_l);+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVMX_ES64(tmp1, ((alen + 64) << 3));+    CVM_LOAD_MD5_UNIT(tmp1, next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_ES64(tmp1, ((64 + 16) << 3));+    CVMX_MT_HSH_STARTMD5(tmp1);++    /* save the HMAC */+    SG_INIT(sg, data, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	icv_off -= 8;+    }+    CVMX_MF_HSH_IV(*data, 0);+    SG_CONSUME(sg, data, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *(uint32_t *)data = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* SHA1 */++int+octo_null_sha1_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    uint64_t *data;+    uint64_t tmp1, tmp2, tmp3;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 ||+	    (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data, data_i, data_l);++    flags = octeon_crypto_enable(&state);++    /* Load SHA1 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);+    CVMX_MT_HSH_IV(od->octo_hminner[2], 2);++    while (auth_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	auth_off -= 8;+    }++    while (auth_len > 0) {+	CVM_LOAD_SHA_UNIT(*data, next);+	auth_len -= 8;+	SG_CONSUME(sg, data, data_i, data_l);+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);+    tmp3 = 0;+    CVMX_MF_HSH_IV(tmp3, 2);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);+    CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    tmp3 |= 0x0000000080000000;+    CVMX_MT_HSH_DAT(tmp3, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));++    /* save the HMAC */+    SG_INIT(sg, data, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data, data_i, data_l);+	icv_off -= 8;+    }+    CVMX_MF_HSH_IV(*data, 0);+    SG_CONSUME(sg, data, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *(uint32_t *)data = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* DES MD5 */++int+octo_des_cbc_md5_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata;+    uint64_t *data = &mydata.data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load 3DES Key */+    CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    if (od->octo_encklen == 24) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+    } else if (od->octo_encklen == 8) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }++    CVMX_MT_3DES_IV(* (uint64_t *) ivp);++    /* Load MD5 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    while (crypt_len > 0 || auth_len > 0) {+    	uint32_t *first = data32;+	mydata.data32[0] = *first;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata.data32[1] = *data32;+    	if (crypt_off <= 0) {+	    if (crypt_len > 0) {+		CVMX_MT_3DES_ENC_CBC(*data);+		CVMX_MF_3DES_RESULT(*data);+		crypt_len -= 8;+	    }+	} else+	    crypt_off -= 8;+    	if (auth_off <= 0) {+	    if (auth_len > 0) {+		CVM_LOAD_MD5_UNIT(*data, next);+		auth_len -= 8;+	    }+	} else+	    auth_off -= 8;+	*first = mydata.data32[0];+	*data32 = mydata.data32[1];+	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVMX_ES64(tmp1, ((alen + 64) << 3));+    CVM_LOAD_MD5_UNIT(tmp1, next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_ES64(tmp1, ((64 + 16) << 3));+    CVMX_MT_HSH_STARTMD5(tmp1);++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++int+octo_des_cbc_md5_decrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata;+    uint64_t *data = &mydata.data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load 3DES Key */+    CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    if (od->octo_encklen == 24) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+    } else if (od->octo_encklen == 8) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }++    CVMX_MT_3DES_IV(* (uint64_t *) ivp);++    /* Load MD5 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    while (crypt_len > 0 || auth_len > 0) {+    	uint32_t *first = data32;+	mydata.data32[0] = *first;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata.data32[1] = *data32;+    	if (auth_off <= 0) {+	    if (auth_len > 0) {+		CVM_LOAD_MD5_UNIT(*data, next);+		auth_len -= 8;+	    }+	} else+	    auth_off -= 8;+    	if (crypt_off <= 0) {+	    if (crypt_len > 0) {+		CVMX_MT_3DES_DEC_CBC(*data);+		CVMX_MF_3DES_RESULT(*data);+		crypt_len -= 8;+	    }+	} else+	    crypt_off -= 8;+	*first = mydata.data32[0];+	*data32 = mydata.data32[1];+	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVMX_ES64(tmp1, ((alen + 64) << 3));+    CVM_LOAD_MD5_UNIT(tmp1, next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_ES64(tmp1, ((64 + 16) << 3));+    CVMX_MT_HSH_STARTMD5(tmp1);++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* DES SHA */++int+octo_des_cbc_sha1_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata;+    uint64_t *data = &mydata.data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2, tmp3;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load 3DES Key */+    CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    if (od->octo_encklen == 24) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+    } else if (od->octo_encklen == 8) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }++    CVMX_MT_3DES_IV(* (uint64_t *) ivp);++    /* Load SHA1 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);+    CVMX_MT_HSH_IV(od->octo_hminner[2], 2);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    while (crypt_len > 0 || auth_len > 0) {+    	uint32_t *first = data32;+	mydata.data32[0] = *first;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata.data32[1] = *data32;+    	if (crypt_off <= 0) {+	    if (crypt_len > 0) {+		CVMX_MT_3DES_ENC_CBC(*data);+		CVMX_MF_3DES_RESULT(*data);+		crypt_len -= 8;+	    }+	} else+	    crypt_off -= 8;+    	if (auth_off <= 0) {+	    if (auth_len > 0) {+		CVM_LOAD_SHA_UNIT(*data, next);+		auth_len -= 8;+	    }+	} else+	    auth_off -= 8;+	*first = mydata.data32[0];+	*data32 = mydata.data32[1];+	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_SHA_UNIT(tmp, next);+    } else {+	CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);+    }+	CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);+    tmp3 = 0;+    CVMX_MF_HSH_IV(tmp3, 2);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);+    CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    tmp3 |= 0x0000000080000000;+    CVMX_MT_HSH_DAT(tmp3, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++int+octo_des_cbc_sha1_decrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata;+    uint64_t *data = &mydata.data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2, tmp3;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load 3DES Key */+    CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    if (od->octo_encklen == 24) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+    } else if (od->octo_encklen == 8) {+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);+	CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }++    CVMX_MT_3DES_IV(* (uint64_t *) ivp);++    /* Load SHA1 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);+    CVMX_MT_HSH_IV(od->octo_hminner[2], 2);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    while (crypt_len > 0 || auth_len > 0) {+    	uint32_t *first = data32;+	mydata.data32[0] = *first;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata.data32[1] = *data32;+    	if (auth_off <= 0) {+	    if (auth_len > 0) {+		CVM_LOAD_SHA_UNIT(*data, next);+		auth_len -= 8;+	    }+	} else+	    auth_off -= 8;+    	if (crypt_off <= 0) {+	    if (crypt_len > 0) {+		CVMX_MT_3DES_DEC_CBC(*data);+		CVMX_MF_3DES_RESULT(*data);+		crypt_len -= 8;+	    }+	} else+	    crypt_off -= 8;+	*first = mydata.data32[0];+	*data32 = mydata.data32[1];+	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_SHA_UNIT(tmp, next);+    } else {+	CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);+    tmp3 = 0;+    CVMX_MF_HSH_IV(tmp3, 2);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);+    CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    tmp3 |= 0x0000000080000000;+    CVMX_MT_HSH_DAT(tmp3, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));+    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* AES MD5 */++int+octo_aes_cbc_md5_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata[2];+    uint64_t *pdata = &mydata[0].data64[0];+    uint64_t *data =  &mydata[1].data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load AES Key */+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);++    if (od->octo_encklen == 16) {+	CVMX_MT_AES_KEY(0x0, 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 24) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 32) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }+    CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);++    CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);+    CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);++    /* Load MD5 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    /* align auth and crypt */+    while (crypt_off > 0 && auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_MD5_UNIT(*pdata, next);+	crypt_off -= 8;+	auth_len -= 8;+    }++    while (crypt_len > 0) {+    	uint32_t *pdata32[3];++	pdata32[0] = data32;+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);++	pdata32[1] = data32;+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);++	pdata32[2] = data32;+	mydata[1].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);++	mydata[1].data32[1] = *data32;++	CVMX_MT_AES_ENC_CBC0(*pdata);+	CVMX_MT_AES_ENC_CBC1(*data);+	CVMX_MF_AES_RESULT(*pdata, 0);+	CVMX_MF_AES_RESULT(*data, 1);+	crypt_len -= 16;++	if (auth_len > 0) {+	    CVM_LOAD_MD5_UNIT(*pdata, next);+	    auth_len -= 8;+	}+	if (auth_len > 0) {+	    CVM_LOAD_MD5_UNIT(*data, next);+	    auth_len -= 8;+	}++	*pdata32[0] = mydata[0].data32[0];+	*pdata32[1] = mydata[0].data32[1];+	*pdata32[2] = mydata[1].data32[0];+	*data32     = mydata[1].data32[1];++	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish any left over hashing */+    while (auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_MD5_UNIT(*pdata, next);+	auth_len -= 8;+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVMX_ES64(tmp1, ((alen + 64) << 3));+    CVM_LOAD_MD5_UNIT(tmp1, next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_ES64(tmp1, ((64 + 16) << 3));+    CVMX_MT_HSH_STARTMD5(tmp1);++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++int+octo_aes_cbc_md5_decrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata[2];+    uint64_t *pdata = &mydata[0].data64[0];+    uint64_t *data =  &mydata[1].data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s()\n", __FUNCTION__);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load AES Key */+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);++    if (od->octo_encklen == 16) {+	CVMX_MT_AES_KEY(0x0, 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 24) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 32) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }+    CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);++    CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);+    CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);++    /* Load MD5 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    /* align auth and crypt */+    while (crypt_off > 0 && auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_MD5_UNIT(*pdata, next);+	crypt_off -= 8;+	auth_len -= 8;+    }++    while (crypt_len > 0) {+    	uint32_t *pdata32[3];++	pdata32[0] = data32;+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	pdata32[1] = data32;+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	pdata32[2] = data32;+	mydata[1].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[1].data32[1] = *data32;++	if (auth_len > 0) {+	    CVM_LOAD_MD5_UNIT(*pdata, next);+	    auth_len -= 8;+	}++	if (auth_len > 0) {+	    CVM_LOAD_MD5_UNIT(*data, next);+	    auth_len -= 8;+	}++	CVMX_MT_AES_DEC_CBC0(*pdata);+	CVMX_MT_AES_DEC_CBC1(*data);+	CVMX_MF_AES_RESULT(*pdata, 0);+	CVMX_MF_AES_RESULT(*data, 1);+	crypt_len -= 16;++	*pdata32[0] = mydata[0].data32[0];+	*pdata32[1] = mydata[0].data32[1];+	*pdata32[2] = mydata[1].data32[0];+	*data32     = mydata[1].data32[1];++	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish left over hash if any */+    while (auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_MD5_UNIT(*pdata, next);+	auth_len -= 8;+    }+++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVMX_ES64(tmp1, ((alen + 64) << 3));+    CVM_LOAD_MD5_UNIT(tmp1, next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_ES64(tmp1, ((64 + 16) << 3));+    CVMX_MT_HSH_STARTMD5(tmp1);++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/+/* AES SHA1 */++int+octo_aes_cbc_sha1_encrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata[2];+    uint64_t *pdata = &mydata[0].data64[0];+    uint64_t *data =  &mydata[1].data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2, tmp3;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",+			__FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load AES Key */+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);++    if (od->octo_encklen == 16) {+	CVMX_MT_AES_KEY(0x0, 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 24) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 32) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }+    CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);++    CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);+    CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);++    /* Load SHA IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);+    CVMX_MT_HSH_IV(od->octo_hminner[2], 2);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    /* align auth and crypt */+    while (crypt_off > 0 && auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_SHA_UNIT(*pdata, next);+	crypt_off -= 8;+	auth_len -= 8;+    }++    while (crypt_len > 0) {+    	uint32_t *pdata32[3];++	pdata32[0] = data32;+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	pdata32[1] = data32;+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	pdata32[2] = data32;+	mydata[1].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[1].data32[1] = *data32;++	CVMX_MT_AES_ENC_CBC0(*pdata);+	CVMX_MT_AES_ENC_CBC1(*data);+	CVMX_MF_AES_RESULT(*pdata, 0);+	CVMX_MF_AES_RESULT(*data, 1);+	crypt_len -= 16;++	if (auth_len > 0) {+	    CVM_LOAD_SHA_UNIT(*pdata, next);+	    auth_len -= 8;+	}+	if (auth_len > 0) {+	    CVM_LOAD_SHA_UNIT(*data, next);+	    auth_len -= 8;+	}++	*pdata32[0] = mydata[0].data32[0];+	*pdata32[1] = mydata[0].data32[1];+	*pdata32[2] = mydata[1].data32[0];+	*data32     = mydata[1].data32[1];++	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish and hashing */+    while (auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_SHA_UNIT(*pdata, next);+	auth_len -= 8;+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_SHA_UNIT(tmp, next);+    } else {+	CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);+    }+    CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);+    tmp3 = 0;+    CVMX_MF_HSH_IV(tmp3, 2);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);+    CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    tmp3 |= 0x0000000080000000;+    CVMX_MT_HSH_DAT(tmp3, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++int+octo_aes_cbc_sha1_decrypt(+    struct octo_sess *od,+    struct scatterlist *sg, int sg_len,+    int auth_off, int auth_len,+    int crypt_off, int crypt_len,+    int icv_off, uint8_t *ivp)+{+    register int next = 0;+    union {+	uint32_t data32[2];+	uint64_t data64[1];+    } mydata[2];+    uint64_t *pdata = &mydata[0].data64[0];+    uint64_t *data =  &mydata[1].data64[0];+    uint32_t *data32;+    uint64_t tmp1, tmp2, tmp3;+    int data_i, data_l, alen = auth_len;+    struct octeon_cop2_state state;+    unsigned long flags;++    dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",+			__FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);++    if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||+	    (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||+	    (crypt_len  & 0x7) ||+	    (auth_len  & 0x7) ||+	    (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {+	dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "+		"auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "+		"icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,+		auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	return -EINVAL;+    }++    SG_INIT(sg, data32, data_i, data_l);++    CVMX_PREFETCH0(ivp);+    CVMX_PREFETCH0(od->octo_enckey);++    flags = octeon_crypto_enable(&state);++    /* load AES Key */+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);+    CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);++    if (od->octo_encklen == 16) {+	CVMX_MT_AES_KEY(0x0, 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 24) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(0x0, 3);+    } else if (od->octo_encklen == 32) {+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);+	CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);+    } else {+	octeon_crypto_disable(&state, flags);+	dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);+	return -EINVAL;+    }+    CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);++    CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);+    CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);++    /* Load SHA1 IV */+    CVMX_MT_HSH_IV(od->octo_hminner[0], 0);+    CVMX_MT_HSH_IV(od->octo_hminner[1], 1);+    CVMX_MT_HSH_IV(od->octo_hminner[2], 2);++    while (crypt_off > 0 && auth_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	crypt_off -= 4;+	auth_off -= 4;+    }++    /* align auth and crypt */+    while (crypt_off > 0 && auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_SHA_UNIT(*pdata, next);+	crypt_off -= 8;+	auth_len -= 8;+    }++    while (crypt_len > 0) {+    	uint32_t *pdata32[3];++	pdata32[0] = data32;+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	pdata32[1] = data32;+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	pdata32[2] = data32;+	mydata[1].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[1].data32[1] = *data32;++	if (auth_len > 0) {+	    CVM_LOAD_SHA_UNIT(*pdata, next);+	    auth_len -= 8;+	}+	if (auth_len > 0) {+	    CVM_LOAD_SHA_UNIT(*data, next);+	    auth_len -= 8;+	}++	CVMX_MT_AES_DEC_CBC0(*pdata);+	CVMX_MT_AES_DEC_CBC1(*data);+	CVMX_MF_AES_RESULT(*pdata, 0);+	CVMX_MF_AES_RESULT(*data, 1);+	crypt_len -= 16;++	*pdata32[0] = mydata[0].data32[0];+	*pdata32[1] = mydata[0].data32[1];+	*pdata32[2] = mydata[1].data32[0];+	*data32     = mydata[1].data32[1];++	SG_CONSUME(sg, data32, data_i, data_l);+    }++    /* finish and leftover hashing */+    while (auth_len > 0) {+	mydata[0].data32[0] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	mydata[0].data32[1] = *data32;+	SG_CONSUME(sg, data32, data_i, data_l);+	CVM_LOAD_SHA_UNIT(*pdata, next);+	auth_len -= 8;+    }++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_SHA_UNIT(tmp, next);+    } else {+	CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);+#endif++    /* Finish Inner hash */+    while (next != 7) {+	CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);+    }+	CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);++    /* Get the inner hash of HMAC */+    CVMX_MF_HSH_IV(tmp1, 0);+    CVMX_MF_HSH_IV(tmp2, 1);+    tmp3 = 0;+    CVMX_MF_HSH_IV(tmp3, 2);++    /* Initialize hash unit */+    CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);+    CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);+    CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);++    CVMX_MT_HSH_DAT(tmp1, 0);+    CVMX_MT_HSH_DAT(tmp2, 1);+    tmp3 |= 0x0000000080000000;+    CVMX_MT_HSH_DAT(tmp3, 2);+    CVMX_MT_HSH_DATZ(3);+    CVMX_MT_HSH_DATZ(4);+    CVMX_MT_HSH_DATZ(5);+    CVMX_MT_HSH_DATZ(6);+    CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));++    /* finish the hash */+    CVMX_PREFETCH0(od->octo_hmouter);+#if 0+    if (unlikely(inplen)) {+	uint64_t tmp = 0;+	uint8_t *p = (uint8_t *) & tmp;+	p[inplen] = 0x80;+	do {+	    inplen--;+	    p[inplen] = ((uint8_t *) data)[inplen];+	} while (inplen);+	CVM_LOAD_MD5_UNIT(tmp, next);+    } else {+	CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+    }+#else+    CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);+#endif++    /* save the HMAC */+    SG_INIT(sg, data32, data_i, data_l);+    while (icv_off > 0) {+	SG_CONSUME(sg, data32, data_i, data_l);+	icv_off -= 4;+    }+    CVMX_MF_HSH_IV(tmp1, 0);+    *data32 = (uint32_t) (tmp1 >> 32);+    SG_CONSUME(sg, data32, data_i, data_l);+    *data32 = (uint32_t) tmp1;+    SG_CONSUME(sg, data32, data_i, data_l);+    CVMX_MF_HSH_IV(tmp1, 1);+    *data32 = (uint32_t) (tmp1 >> 32);++    octeon_crypto_disable(&state, flags);+    return 0;+}++/****************************************************************************/diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/cryptocteon.c linux-2.6.36/crypto/ocf/cryptocteon/cryptocteon.c--- linux-2.6.36.orig/crypto/ocf/cryptocteon/cryptocteon.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/cryptocteon/cryptocteon.c	2010-11-09 20:28:04.371247488 +0100@@ -0,0 +1,574 @@+/*+ * Octeon Crypto for OCF+ *+ * Written by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2009-2010 David McCullough+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ * ---------------------------------------------------------------------------+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/sched.h>+#include <linux/wait.h>+#include <linux/crypto.h>+#include <linux/mm.h>+#include <linux/skbuff.h>+#include <linux/random.h>+#include <linux/scatterlist.h>++#include <cryptodev.h>+#include <uio.h>++struct {+	softc_device_decl	sc_dev;+} octo_softc;++#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)++struct octo_sess {+	int					 octo_encalg;+	#define MAX_CIPHER_KEYLEN	64+	char				 octo_enckey[MAX_CIPHER_KEYLEN];+	int					 octo_encklen;++	int					 octo_macalg;+	#define MAX_HASH_KEYLEN	64+	char				 octo_mackey[MAX_HASH_KEYLEN];+	int					 octo_macklen;+	int					 octo_mackey_set;++	int					 octo_mlen;+	int					 octo_ivsize;++#if 0+	int					(*octo_decrypt)(struct scatterlist *sg, int sg_len,+							uint8_t *key, int key_len, uint8_t * iv,+							uint64_t *hminner, uint64_t *hmouter);++	int					(*octo_encrypt)(struct scatterlist *sg, int sg_len,+							uint8_t *key, int key_len, uint8_t * iv,+							uint64_t *hminner, uint64_t *hmouter);+#else+	int					(*octo_encrypt)(struct octo_sess *od,+	                      struct scatterlist *sg, int sg_len,+						  int auth_off, int auth_len,+						  int crypt_off, int crypt_len,+						  int icv_off, uint8_t *ivp);+	int					(*octo_decrypt)(struct octo_sess *od,+	                      struct scatterlist *sg, int sg_len,+						  int auth_off, int auth_len,+						  int crypt_off, int crypt_len,+						  int icv_off, uint8_t *ivp);+#endif++	uint64_t			 octo_hminner[3];+	uint64_t			 octo_hmouter[3];+};++int32_t octo_id = -1;+module_param(octo_id, int, 0444);+MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver");++static struct octo_sess **octo_sessions = NULL;+static u_int32_t octo_sesnum = 0;++static	int octo_process(device_t, struct cryptop *, int);+static	int octo_newsession(device_t, u_int32_t *, struct cryptoini *);+static	int octo_freesession(device_t, u_int64_t);++static device_method_t octo_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	octo_newsession),+	DEVMETHOD(cryptodev_freesession,octo_freesession),+	DEVMETHOD(cryptodev_process,	octo_process),+};++#define debug octo_debug+int octo_debug = 0;+module_param(octo_debug, int, 0644);+MODULE_PARM_DESC(octo_debug, "Enable debug");+++#include "cavium_crypto.c"+++/*+ * Generate a new octo session.  We artifically limit it to a single+ * hash/cipher or hash-cipher combo just to make it easier, most callers+ * do not expect more than this anyway.+ */+static int+octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)+{+	struct cryptoini *c, *encini = NULL, *macini = NULL;+	struct octo_sess **ocd;+	int i;++	dprintk("%s()\n", __FUNCTION__);+	if (sid == NULL || cri == NULL) {+		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	/*+	 * To keep it simple, we only handle hash, cipher or hash/cipher in a+	 * session,  you cannot currently do multiple ciphers/hashes in one+	 * session even though it would be possibel to code this driver to+	 * handle it.+	 */+	for (i = 0, c = cri; c && i < 2; i++) {+		if (c->cri_alg == CRYPTO_MD5_HMAC ||+				c->cri_alg == CRYPTO_SHA1_HMAC ||+				c->cri_alg == CRYPTO_NULL_HMAC) {+			if (macini) {+				break;+			}+			macini = c;+		}+		if (c->cri_alg == CRYPTO_DES_CBC ||+				c->cri_alg == CRYPTO_3DES_CBC ||+				c->cri_alg == CRYPTO_AES_CBC ||+				c->cri_alg == CRYPTO_NULL_CBC) {+			if (encini) {+				break;+			}+			encini = c;+		}+		c = c->cri_next;+	}+	if (!macini && !encini) {+		dprintk("%s,%d - EINVAL bad cipher/hash or combination\n",+				__FILE__, __LINE__);+		return EINVAL;+	}+	if (c) {+		dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n",+				__FILE__, __LINE__);+		return EINVAL;+	}++	/*+	 * So we have something we can do, lets setup the session+	 */++	if (octo_sessions) {+		for (i = 1; i < octo_sesnum; i++)+			if (octo_sessions[i] == NULL)+				break;+	} else+		i = 1;		/* NB: to silence compiler warning */++	if (octo_sessions == NULL || i == octo_sesnum) {+		if (octo_sessions == NULL) {+			i = 1; /* We leave octo_sessions[0] empty */+			octo_sesnum = CRYPTO_SW_SESSIONS;+		} else+			octo_sesnum *= 2;++		ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC);+		if (ocd == NULL) {+			/* Reset session number */+			if (octo_sesnum == CRYPTO_SW_SESSIONS)+				octo_sesnum = 0;+			else+				octo_sesnum /= 2;+			dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+			return ENOBUFS;+		}+		memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *));++		/* Copy existing sessions */+		if (octo_sessions) {+			memcpy(ocd, octo_sessions,+			    (octo_sesnum / 2) * sizeof(struct octo_sess *));+			kfree(octo_sessions);+		}++		octo_sessions = ocd;+	}++	ocd = &octo_sessions[i];+	*sid = i;+++	*ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC);+	if (*ocd == NULL) {+		octo_freesession(NULL, i);+		dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+		return ENOBUFS;+	}+	memset(*ocd, 0, sizeof(struct octo_sess));++	if (encini && encini->cri_key) {+		(*ocd)->octo_encklen = (encini->cri_klen + 7) / 8;+		memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen);+	}++	if (macini && macini->cri_key) {+		(*ocd)->octo_macklen = (macini->cri_klen + 7) / 8;+		memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen);+	}++	(*ocd)->octo_mlen = 0;+	if (encini && encini->cri_mlen)+		(*ocd)->octo_mlen = encini->cri_mlen;+	else if (macini && macini->cri_mlen)+		(*ocd)->octo_mlen = macini->cri_mlen;+	else+		(*ocd)->octo_mlen = 12;++	/*+	 * point c at the enc if it exists, otherwise the mac+	 */+	c = encini ? encini : macini;++	switch (c->cri_alg) {+	case CRYPTO_DES_CBC:+	case CRYPTO_3DES_CBC:+		(*ocd)->octo_ivsize  = 8;+		switch (macini ? macini->cri_alg : -1) {+		case CRYPTO_MD5_HMAC:+			(*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt;+			(*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt;+			octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,+					(*ocd)->octo_hmouter);+			break;+		case CRYPTO_SHA1_HMAC:+			(*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;+			(*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;+			octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,+					(*ocd)->octo_hmouter);+			break;+		case -1:+			(*ocd)->octo_encrypt = octo_des_cbc_encrypt;+			(*ocd)->octo_decrypt = octo_des_cbc_decrypt;+			break;+		default:+			octo_freesession(NULL, i);+			dprintk("%s,%d: EINVALn", __FILE__, __LINE__);+			return EINVAL;+		}+		break;+	case CRYPTO_AES_CBC:+		(*ocd)->octo_ivsize  = 16;+		switch (macini ? macini->cri_alg : -1) {+		case CRYPTO_MD5_HMAC:+			(*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt;+			(*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt;+			octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,+					(*ocd)->octo_hmouter);+			break;+		case CRYPTO_SHA1_HMAC:+			(*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt;+			(*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt;+			octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,+					(*ocd)->octo_hmouter);+			break;+		case -1:+			(*ocd)->octo_encrypt = octo_aes_cbc_encrypt;+			(*ocd)->octo_decrypt = octo_aes_cbc_decrypt;+			break;+		default:+			octo_freesession(NULL, i);+			dprintk("%s,%d: EINVALn", __FILE__, __LINE__);+			return EINVAL;+		}+		break;+	case CRYPTO_MD5_HMAC:+		(*ocd)->octo_encrypt = octo_null_md5_encrypt;+		(*ocd)->octo_decrypt = octo_null_md5_encrypt;+		octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,+				(*ocd)->octo_hmouter);+		break;+	case CRYPTO_SHA1_HMAC:+		(*ocd)->octo_encrypt = octo_null_sha1_encrypt;+		(*ocd)->octo_decrypt = octo_null_sha1_encrypt;+		octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,+				(*ocd)->octo_hmouter);+		break;+	default:+		octo_freesession(NULL, i);+		dprintk("%s,%d: EINVALn", __FILE__, __LINE__);+		return EINVAL;+	}++	(*ocd)->octo_encalg = encini ? encini->cri_alg : -1;+	(*ocd)->octo_macalg = macini ? macini->cri_alg : -1;++	return 0;+}++/*+ * Free a session.+ */+static int+octo_freesession(device_t dev, u_int64_t tid)+{+	u_int32_t sid = CRYPTO_SESID2LID(tid);++	dprintk("%s()\n", __FUNCTION__);+	if (sid > octo_sesnum || octo_sessions == NULL ||+			octo_sessions[sid] == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return(EINVAL);+	}++	/* Silently accept and return */+	if (sid == 0)+		return(0);++	if (octo_sessions[sid])+		kfree(octo_sessions[sid]);+	octo_sessions[sid] = NULL;+	return 0;+}++/*+ * Process a request.+ */+static int+octo_process(device_t dev, struct cryptop *crp, int hint)+{+	struct cryptodesc *crd;+	struct octo_sess *od;+	u_int32_t lid;+#define SCATTERLIST_MAX 16+	struct scatterlist sg[SCATTERLIST_MAX];+	int sg_num, sg_len;+	struct sk_buff *skb = NULL;+	struct uio *uiop = NULL;+	struct cryptodesc *enccrd = NULL, *maccrd = NULL;+	unsigned char *ivp = NULL;+	unsigned char iv_data[HASH_MAX_LEN];+	int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0;++	dprintk("%s()\n", __FUNCTION__);+	/* Sanity check */+	if (crp == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	crp->crp_etype = 0;++	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	}++	lid = crp->crp_sid & 0xffffffff;+	if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL ||+			octo_sessions[lid] == NULL) {+		crp->crp_etype = ENOENT;+		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);+		goto done;+	}+	od = octo_sessions[lid];++	/*+	 * do some error checking outside of the loop for SKB and IOV processing+	 * this leaves us with valid skb or uiop pointers for later+	 */+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		skb = (struct sk_buff *) crp->crp_buf;+		if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {+			printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,+					skb_shinfo(skb)->nr_frags);+			goto done;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		uiop = (struct uio *) crp->crp_buf;+		if (uiop->uio_iovcnt > SCATTERLIST_MAX) {+			printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,+					uiop->uio_iovcnt);+			goto done;+		}+	}++	/* point our enccrd and maccrd appropriately */+	crd = crp->crp_desc;+	if (crd->crd_alg == od->octo_encalg) enccrd = crd;+	if (crd->crd_alg == od->octo_macalg) maccrd = crd;+	crd = crd->crd_next;+	if (crd) {+		if (crd->crd_alg == od->octo_encalg) enccrd = crd;+		if (crd->crd_alg == od->octo_macalg) maccrd = crd;+		crd = crd->crd_next;+	}+	if (crd) {+		crp->crp_etype = EINVAL;+		dprintk("%s,%d: ENOENT - descriptors do not match session\n",+				__FILE__, __LINE__);+		goto done;+	}++	if (enccrd) {+		if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {+			ivp = enccrd->crd_iv;+		} else {+			ivp = iv_data;+			crypto_copydata(crp->crp_flags, crp->crp_buf,+					enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);+		}++		if (maccrd) {+			auth_off = maccrd->crd_skip;+			auth_len = maccrd->crd_len;+			icv_off  = maccrd->crd_inject;+		}++		crypt_off = enccrd->crd_skip;+		crypt_len = enccrd->crd_len;+	} else { /* if (maccrd) */+		auth_off = maccrd->crd_skip;+		auth_len = maccrd->crd_len;+		icv_off  = maccrd->crd_inject;+	}+++	/*+	 * setup the SG list to cover the buffer+	 */+	memset(sg, 0, sizeof(sg));+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		int i, len;++		sg_num = 0;+		sg_len = 0;++		len = skb_headlen(skb);+		sg_set_page(&sg[sg_num], virt_to_page(skb->data), len,+				offset_in_page(skb->data));+		sg_len += len;+		sg_num++;++		for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX;+				i++) {+			len = skb_shinfo(skb)->frags[i].size;+			sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page,+					len, skb_shinfo(skb)->frags[i].page_offset);+			sg_len += len;+			sg_num++;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		int len;++		sg_len = 0;+		for (sg_num = 0; sg_len < crp->crp_ilen &&+				sg_num < uiop->uio_iovcnt &&+				sg_num < SCATTERLIST_MAX; sg_num++) {+			len = uiop->uio_iov[sg_num].iov_len;+			sg_set_page(&sg[sg_num],+					virt_to_page(uiop->uio_iov[sg_num].iov_base), len,+					offset_in_page(uiop->uio_iov[sg_num].iov_base));+			sg_len += len;+		}+	} else {+		sg_len = crp->crp_ilen;+		sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len,+				offset_in_page(crp->crp_buf));+		sg_num = 1;+	}+++	/*+	 * setup a new explicit key+	 */+	if (enccrd) {+		if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {+			od->octo_encklen = (enccrd->crd_klen + 7) / 8;+			memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen);+		}+	}+	if (maccrd) {+		if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {+			od->octo_macklen = (maccrd->crd_klen + 7) / 8;+			memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen);+			od->octo_mackey_set = 0;+		}+		if (!od->octo_mackey_set) {+			octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1,+				maccrd->crd_key, od->octo_hminner, od->octo_hmouter);+			od->octo_mackey_set = 1;+		}+	}+++	if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT))+		(*od->octo_encrypt)(od, sg, sg_len,+				auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);+	else+		(*od->octo_decrypt)(od, sg, sg_len,+				auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);++done:+	crypto_done(crp);+	return 0;+}++static int+cryptocteon_init(void)+{+	dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init);++	softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods);++	octo_id = crypto_get_driverid(softc_get_device(&octo_softc),+			CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC);+	if (octo_id < 0) {+		printk("Cryptocteon device cannot initialize!");+		return -ENODEV;+	}++	crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0);+	crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0);+	//crypto_register(octo_id, CRYPTO_MD5, 0,0);+	//crypto_register(octo_id, CRYPTO_SHA1, 0,0);+	crypto_register(octo_id, CRYPTO_DES_CBC, 0,0);+	crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0);+	crypto_register(octo_id, CRYPTO_AES_CBC, 0,0);++	return(0);+}++static void+cryptocteon_exit(void)+{+	dprintk("%s()\n", __FUNCTION__);+	crypto_unregister_all(octo_id);+	octo_id = -1;+}++module_init(cryptocteon_init);+module_exit(cryptocteon_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)");diff -Nur linux-2.6.36.orig/crypto/ocf/cryptocteon/Makefile linux-2.6.36/crypto/ocf/cryptocteon/Makefile--- linux-2.6.36.orig/crypto/ocf/cryptocteon/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/cryptocteon/Makefile	2010-11-09 20:28:04.411246358 +0100@@ -0,0 +1,17 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/++ifdef CONFIG_OCF_CRYPTOCTEON+# you need the cavium crypto component installed+EXTRA_CFLAGS += -I$(ROOTDIR)/prop/include+endif++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/cryptodev.c linux-2.6.36/crypto/ocf/cryptodev.c--- linux-2.6.36.orig/crypto/ocf/cryptodev.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/cryptodev.c	2010-11-09 20:29:09.284996310 +0100@@ -0,0 +1,1060 @@+/*	$OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $	*/++/*-+ * Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ * The license and original author are listed below.+ *+ * Copyright (c) 2001 Theo de Raadt+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/types.h>+#include <linux/time.h>+#include <linux/delay.h>+#include <linux/list.h>+#include <linux/init.h>+#include <linux/sched.h>+#include <linux/unistd.h>+#include <linux/module.h>+#include <linux/wait.h>+#include <linux/slab.h>+#include <linux/fs.h>+#include <linux/dcache.h>+#include <linux/file.h>+#include <linux/mount.h>+#include <linux/miscdevice.h>+#include <linux/version.h>+#include <asm/uaccess.h>++#include <cryptodev.h>+#include <uio.h>++extern asmlinkage long sys_dup(unsigned int fildes);++#define debug cryptodev_debug+int cryptodev_debug = 0;+module_param(cryptodev_debug, int, 0644);+MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");++struct csession_info {+	u_int16_t	blocksize;+	u_int16_t	minkey, maxkey;++	u_int16_t	keysize;+	/* u_int16_t	hashsize;  */+	u_int16_t	authsize;+	u_int16_t	authkey;+	/* u_int16_t	ctxsize; */+};++struct csession {+	struct list_head	list;+	u_int64_t	sid;+	u_int32_t	ses;++	wait_queue_head_t waitq;++	u_int32_t	cipher;++	u_int32_t	mac;++	caddr_t		key;+	int		keylen;+	u_char		tmp_iv[EALG_MAX_BLOCK_LEN];++	caddr_t		mackey;+	int		mackeylen;++	struct csession_info info;++	struct iovec	iovec;+	struct uio	uio;+	int		error;+};++struct fcrypt {+	struct list_head	csessions;+	int		sesn;+};++static struct csession *csefind(struct fcrypt *, u_int);+static int csedelete(struct fcrypt *, struct csession *);+static struct csession *cseadd(struct fcrypt *, struct csession *);+static struct csession *csecreate(struct fcrypt *, u_int64_t,+		struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);+static int csefree(struct csession *);++static	int cryptodev_op(struct csession *, struct crypt_op *);+static	int cryptodev_key(struct crypt_kop *);+static	int cryptodev_find(struct crypt_find_op *);++static int cryptodev_cb(void *);+static int cryptodev_open(struct inode *inode, struct file *filp);++/*+ * Check a crypto identifier to see if it requested+ * a valid crid and it's capabilities match.+ */+static int+checkcrid(int crid)+{+	int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);+	int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);+	int caps = 0;+	+	/* if the user hasn't selected a driver, then just call newsession */+	if (hid == 0 && typ != 0)+		return 0;++	caps = crypto_getcaps(hid);++	/* didn't find anything with capabilities */+	if (caps == 0) {+		dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);+		return EINVAL;+	}+	+	/* the user didn't specify SW or HW, so the driver is ok */+	if (typ == 0)+		return 0;++	/* if the type specified didn't match */+	if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {+		dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,+				hid, typ, caps);+		return EINVAL;+	}++	return 0;+}++static int+cryptodev_op(struct csession *cse, struct crypt_op *cop)+{+	struct cryptop *crp = NULL;+	struct cryptodesc *crde = NULL, *crda = NULL;+	int error = 0;++	dprintk("%s()\n", __FUNCTION__);+	if (cop->len > CRYPTO_MAX_DATA_LEN) {+		dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);+		return (E2BIG);+	}++	if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {+		dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,+				cop->len);+		return (EINVAL);+	}++	cse->uio.uio_iov = &cse->iovec;+	cse->uio.uio_iovcnt = 1;+	cse->uio.uio_offset = 0;+#if 0+	cse->uio.uio_resid = cop->len;+	cse->uio.uio_segflg = UIO_SYSSPACE;+	cse->uio.uio_rw = UIO_WRITE;+	cse->uio.uio_td = td;+#endif+	cse->uio.uio_iov[0].iov_len = cop->len;+	if (cse->info.authsize)+		cse->uio.uio_iov[0].iov_len += cse->info.authsize;+	cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,+			GFP_KERNEL);++	if (cse->uio.uio_iov[0].iov_base == NULL) {+		dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,+				(int)cse->uio.uio_iov[0].iov_len);+		return (ENOMEM);+	}++	crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));+	if (crp == NULL) {+		dprintk("%s: ENOMEM\n", __FUNCTION__);+		error = ENOMEM;+		goto bail;+	}++	if (cse->info.authsize && cse->info.blocksize) {+		if (cop->op == COP_ENCRYPT) {+			crde = crp->crp_desc;+			crda = crde->crd_next;+		} else {+			crda = crp->crp_desc;+			crde = crda->crd_next;+		}+	} else if (cse->info.authsize) {+		crda = crp->crp_desc;+	} else if (cse->info.blocksize) {+		crde = crp->crp_desc;+	} else {+		dprintk("%s: bad request\n", __FUNCTION__);+		error = EINVAL;+		goto bail;+	}++	if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,+					cop->len))) {+		dprintk("%s: bad copy\n", __FUNCTION__);+		goto bail;+	}++	if (crda) {+		crda->crd_skip = 0;+		crda->crd_len = cop->len;+		crda->crd_inject = cop->len;++		crda->crd_alg = cse->mac;+		crda->crd_key = cse->mackey;+		crda->crd_klen = cse->mackeylen * 8;+	}++	if (crde) {+		if (cop->op == COP_ENCRYPT)+			crde->crd_flags |= CRD_F_ENCRYPT;+		else+			crde->crd_flags &= ~CRD_F_ENCRYPT;+		crde->crd_len = cop->len;+		crde->crd_inject = 0;++		crde->crd_alg = cse->cipher;+		crde->crd_key = cse->key;+		crde->crd_klen = cse->keylen * 8;+	}++	crp->crp_ilen = cse->uio.uio_iov[0].iov_len;+	crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM+		       | (cop->flags & COP_F_BATCH);+	crp->crp_buf = (caddr_t)&cse->uio;+	crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;+	crp->crp_sid = cse->sid;+	crp->crp_opaque = (void *)cse;++	if (cop->iv) {+		if (crde == NULL) {+			error = EINVAL;+			dprintk("%s no crde\n", __FUNCTION__);+			goto bail;+		}+		if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */+			error = EINVAL;+			dprintk("%s arc4 with IV\n", __FUNCTION__);+			goto bail;+		}+		if ((error = copy_from_user(cse->tmp_iv, cop->iv,+						cse->info.blocksize))) {+			dprintk("%s bad iv copy\n", __FUNCTION__);+			goto bail;+		}+		memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);+		crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;+		crde->crd_skip = 0;+	} else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */+		crde->crd_skip = 0;+	} else if (crde) {+		crde->crd_flags |= CRD_F_IV_PRESENT;+		crde->crd_skip = cse->info.blocksize;+		crde->crd_len -= cse->info.blocksize;+	}++	if (cop->mac && crda == NULL) {+		error = EINVAL;+		dprintk("%s no crda\n", __FUNCTION__);+		goto bail;+	}++	/*+	 * Let the dispatch run unlocked, then, interlock against the+	 * callback before checking if the operation completed and going+	 * to sleep.  This insures drivers don't inherit our lock which+	 * results in a lock order reversal between crypto_dispatch forced+	 * entry and the crypto_done callback into us.+	 */+	error = crypto_dispatch(crp);+	if (error) {+		dprintk("%s error in crypto_dispatch\n", __FUNCTION__);+		goto bail;+	}++	dprintk("%s about to WAIT\n", __FUNCTION__);+	/*+	 * we really need to wait for driver to complete to maintain+	 * state,  luckily interrupts will be remembered+	 */+	do {+		error = wait_event_interruptible(crp->crp_waitq,+				((crp->crp_flags & CRYPTO_F_DONE) != 0));+		/*+		 * we can't break out of this loop or we will leave behind+		 * a huge mess,  however,  staying here means if your driver+		 * is broken user applications can hang and not be killed.+		 * The solution,  fix your driver :-)+		 */+		if (error) {+			schedule();+			error = 0;+		}+	} while ((crp->crp_flags & CRYPTO_F_DONE) == 0);+	dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);++	if (crp->crp_etype != 0) {+		error = crp->crp_etype;+		dprintk("%s error in crp processing\n", __FUNCTION__);+		goto bail;+	}++	if (cse->error) {+		error = cse->error;+		dprintk("%s error in cse processing\n", __FUNCTION__);+		goto bail;+	}++	if (cop->dst && (error = copy_to_user(cop->dst,+					cse->uio.uio_iov[0].iov_base, cop->len))) {+		dprintk("%s bad dst copy\n", __FUNCTION__);+		goto bail;+	}++	if (cop->mac &&+			(error=copy_to_user(cop->mac,+				(caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,+				cse->info.authsize))) {+		dprintk("%s bad mac copy\n", __FUNCTION__);+		goto bail;+	}++bail:+	if (crp)+		crypto_freereq(crp);+	if (cse->uio.uio_iov[0].iov_base)+		kfree(cse->uio.uio_iov[0].iov_base);++	return (error);+}++static int+cryptodev_cb(void *op)+{+	struct cryptop *crp = (struct cryptop *) op;+	struct csession *cse = (struct csession *)crp->crp_opaque;+	int error;++	dprintk("%s()\n", __FUNCTION__);+	error = crp->crp_etype;+	if (error == EAGAIN) {+		crp->crp_flags &= ~CRYPTO_F_DONE;+#ifdef NOTYET+		/*+		 * DAVIDM I am fairly sure that we should turn this into a batch+		 * request to stop bad karma/lockup, revisit+		 */+		crp->crp_flags |= CRYPTO_F_BATCH;+#endif+		return crypto_dispatch(crp);+	}+	if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {+		cse->error = error;+		wake_up_interruptible(&crp->crp_waitq);+	}+	return (0);+}++static int+cryptodevkey_cb(void *op)+{+	struct cryptkop *krp = (struct cryptkop *) op;+	dprintk("%s()\n", __FUNCTION__);+	wake_up_interruptible(&krp->krp_waitq);+	return (0);+}++static int+cryptodev_key(struct crypt_kop *kop)+{+	struct cryptkop *krp = NULL;+	int error = EINVAL;+	int in, out, size, i;++	dprintk("%s()\n", __FUNCTION__);+	if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {+		dprintk("%s params too big\n", __FUNCTION__);+		return (EFBIG);+	}++	in = kop->crk_iparams;+	out = kop->crk_oparams;+	switch (kop->crk_op) {+	case CRK_MOD_EXP:+		if (in == 3 && out == 1)+			break;+		return (EINVAL);+	case CRK_MOD_EXP_CRT:+		if (in == 6 && out == 1)+			break;+		return (EINVAL);+	case CRK_DSA_SIGN:+		if (in == 5 && out == 2)+			break;+		return (EINVAL);+	case CRK_DSA_VERIFY:+		if (in == 7 && out == 0)+			break;+		return (EINVAL);+	case CRK_DH_COMPUTE_KEY:+		if (in == 3 && out == 1)+			break;+		return (EINVAL);+	default:+		return (EINVAL);+	}++	krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);+	if (!krp)+		return (ENOMEM);+	bzero(krp, sizeof *krp);+	krp->krp_op = kop->crk_op;+	krp->krp_status = kop->crk_status;+	krp->krp_iparams = kop->crk_iparams;+	krp->krp_oparams = kop->crk_oparams;+	krp->krp_crid = kop->crk_crid;+	krp->krp_status = 0;+	krp->krp_flags = CRYPTO_KF_CBIMM;+	krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;+	init_waitqueue_head(&krp->krp_waitq);++	for (i = 0; i < CRK_MAXPARAM; i++)+		krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;+	for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {+		size = (krp->krp_param[i].crp_nbits + 7) / 8;+		if (size == 0)+			continue;+		krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);+		if (i >= krp->krp_iparams)+			continue;+		error = copy_from_user(krp->krp_param[i].crp_p,+				kop->crk_param[i].crp_p, size);+		if (error)+			goto fail;+	}++	error = crypto_kdispatch(krp);+	if (error)+		goto fail;++	do {+		error = wait_event_interruptible(krp->krp_waitq,+				((krp->krp_flags & CRYPTO_KF_DONE) != 0));+		/*+		 * we can't break out of this loop or we will leave behind+		 * a huge mess,  however,  staying here means if your driver+		 * is broken user applications can hang and not be killed.+		 * The solution,  fix your driver :-)+		 */+		if (error) {+			schedule();+			error = 0;+		}+	} while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);++	dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);+	+	kop->crk_crid = krp->krp_crid;		/* device that did the work */+	if (krp->krp_status != 0) {+		error = krp->krp_status;+		goto fail;+	}++	for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {+		size = (krp->krp_param[i].crp_nbits + 7) / 8;+		if (size == 0)+			continue;+		error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,+				size);+		if (error)+			goto fail;+	}++fail:+	if (krp) {+		kop->crk_status = krp->krp_status;+		for (i = 0; i < CRK_MAXPARAM; i++) {+			if (krp->krp_param[i].crp_p)+				kfree(krp->krp_param[i].crp_p);+		}+		kfree(krp);+	}+	return (error);+}++static int+cryptodev_find(struct crypt_find_op *find)+{+	device_t dev;++	if (find->crid != -1) {+		dev = crypto_find_device_byhid(find->crid);+		if (dev == NULL)+			return (ENOENT);+		strlcpy(find->name, device_get_nameunit(dev),+		    sizeof(find->name));+	} else {+		find->crid = crypto_find_driver(find->name);+		if (find->crid == -1)+			return (ENOENT);+	}+	return (0);+}++static struct csession *+csefind(struct fcrypt *fcr, u_int ses)+{+	struct csession *cse;++	dprintk("%s()\n", __FUNCTION__);+	list_for_each_entry(cse, &fcr->csessions, list)+		if (cse->ses == ses)+			return (cse);+	return (NULL);+}++static int+csedelete(struct fcrypt *fcr, struct csession *cse_del)+{+	struct csession *cse;++	dprintk("%s()\n", __FUNCTION__);+	list_for_each_entry(cse, &fcr->csessions, list) {+		if (cse == cse_del) {+			list_del(&cse->list);+			return (1);+		}+	}+	return (0);+}+	+static struct csession *+cseadd(struct fcrypt *fcr, struct csession *cse)+{+	dprintk("%s()\n", __FUNCTION__);+	list_add_tail(&cse->list, &fcr->csessions);+	cse->ses = fcr->sesn++;+	return (cse);+}++static struct csession *+csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,+	struct cryptoini *cria, struct csession_info *info)+{+	struct csession *cse;++	dprintk("%s()\n", __FUNCTION__);+	cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);+	if (cse == NULL)+		return NULL;+	memset(cse, 0, sizeof(struct csession));++	INIT_LIST_HEAD(&cse->list);+	init_waitqueue_head(&cse->waitq);++	cse->key = crie->cri_key;+	cse->keylen = crie->cri_klen/8;+	cse->mackey = cria->cri_key;+	cse->mackeylen = cria->cri_klen/8;+	cse->sid = sid;+	cse->cipher = crie->cri_alg;+	cse->mac = cria->cri_alg;+	cse->info = *info;+	cseadd(fcr, cse);+	return (cse);+}++static int+csefree(struct csession *cse)+{+	int error;++	dprintk("%s()\n", __FUNCTION__);+	error = crypto_freesession(cse->sid);+	if (cse->key)+		kfree(cse->key);+	if (cse->mackey)+		kfree(cse->mackey);+	kfree(cse);+	return(error);+}++static int+cryptodev_ioctl(+	struct inode *inode,+	struct file *filp,+	unsigned int cmd,+	unsigned long arg)+{+	struct cryptoini cria, crie;+	struct fcrypt *fcr = filp->private_data;+	struct csession *cse;+	struct csession_info info;+	struct session2_op sop;+	struct crypt_op cop;+	struct crypt_kop kop;+	struct crypt_find_op fop;+	u_int64_t sid;+	u_int32_t ses = 0;+	int feat, fd, error = 0, crid;+	mm_segment_t fs;++	dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);++	switch (cmd) {++	case CRIOGET: {+		dprintk("%s(CRIOGET)\n", __FUNCTION__);+		fs = get_fs();+		set_fs(get_ds());+		for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)+			if (files_fdtable(current->files)->fd[fd] == filp)+				break;+		fd = sys_dup(fd);+		set_fs(fs);+		put_user(fd, (int *) arg);+		return IS_ERR_VALUE(fd) ? fd : 0;+		}++#define	CIOCGSESSSTR	(cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")+	case CIOCGSESSION:+	case CIOCGSESSION2:+		dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);+		memset(&crie, 0, sizeof(crie));+		memset(&cria, 0, sizeof(cria));+		memset(&info, 0, sizeof(info));+		memset(&sop, 0, sizeof(sop));++		if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?+					sizeof(struct session_op) : sizeof(sop))) {+			dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);+			error = EFAULT;+			goto bail;+		}++		switch (sop.cipher) {+		case 0:+			dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);+			break;+		case CRYPTO_NULL_CBC:+			info.blocksize = NULL_BLOCK_LEN;+			info.minkey = NULL_MIN_KEY_LEN;+			info.maxkey = NULL_MAX_KEY_LEN;+			break;+		case CRYPTO_DES_CBC:+			info.blocksize = DES_BLOCK_LEN;+			info.minkey = DES_MIN_KEY_LEN;+			info.maxkey = DES_MAX_KEY_LEN;+			break;+		case CRYPTO_3DES_CBC:+			info.blocksize = DES3_BLOCK_LEN;+			info.minkey = DES3_MIN_KEY_LEN;+			info.maxkey = DES3_MAX_KEY_LEN;+			break;+		case CRYPTO_BLF_CBC:+			info.blocksize = BLOWFISH_BLOCK_LEN;+			info.minkey = BLOWFISH_MIN_KEY_LEN;+			info.maxkey = BLOWFISH_MAX_KEY_LEN;+			break;+		case CRYPTO_CAST_CBC:+			info.blocksize = CAST128_BLOCK_LEN;+			info.minkey = CAST128_MIN_KEY_LEN;+			info.maxkey = CAST128_MAX_KEY_LEN;+			break;+		case CRYPTO_SKIPJACK_CBC:+			info.blocksize = SKIPJACK_BLOCK_LEN;+			info.minkey = SKIPJACK_MIN_KEY_LEN;+			info.maxkey = SKIPJACK_MAX_KEY_LEN;+			break;+		case CRYPTO_AES_CBC:+			info.blocksize = AES_BLOCK_LEN;+			info.minkey = AES_MIN_KEY_LEN;+			info.maxkey = AES_MAX_KEY_LEN;+			break;+		case CRYPTO_ARC4:+			info.blocksize = ARC4_BLOCK_LEN;+			info.minkey = ARC4_MIN_KEY_LEN;+			info.maxkey = ARC4_MAX_KEY_LEN;+			break;+		case CRYPTO_CAMELLIA_CBC:+			info.blocksize = CAMELLIA_BLOCK_LEN;+			info.minkey = CAMELLIA_MIN_KEY_LEN;+			info.maxkey = CAMELLIA_MAX_KEY_LEN;+			break;+		default:+			dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);+			error = EINVAL;+			goto bail;+		}++		switch (sop.mac) {+		case 0:+			dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);+			break;+		case CRYPTO_NULL_HMAC:+			info.authsize = NULL_HASH_LEN;+			break;+		case CRYPTO_MD5:+			info.authsize = MD5_HASH_LEN;+			break;+		case CRYPTO_SHA1:+			info.authsize = SHA1_HASH_LEN;+			break;+		case CRYPTO_SHA2_256:+			info.authsize = SHA2_256_HASH_LEN;+			break;+		case CRYPTO_SHA2_384:+			info.authsize = SHA2_384_HASH_LEN;+  			break;+		case CRYPTO_SHA2_512:+			info.authsize = SHA2_512_HASH_LEN;+			break;+		case CRYPTO_RIPEMD160:+			info.authsize = RIPEMD160_HASH_LEN;+			break;+		case CRYPTO_MD5_HMAC:+			info.authsize = MD5_HASH_LEN;+			info.authkey = 16;+			break;+		case CRYPTO_SHA1_HMAC:+			info.authsize = SHA1_HASH_LEN;+			info.authkey = 20;+			break;+		case CRYPTO_SHA2_256_HMAC:+			info.authsize = SHA2_256_HASH_LEN;+			info.authkey = 32;+			break;+		case CRYPTO_SHA2_384_HMAC:+			info.authsize = SHA2_384_HASH_LEN;+			info.authkey = 48;+  			break;+		case CRYPTO_SHA2_512_HMAC:+			info.authsize = SHA2_512_HASH_LEN;+			info.authkey = 64;+			break;+		case CRYPTO_RIPEMD160_HMAC:+			info.authsize = RIPEMD160_HASH_LEN;+			info.authkey = 20;+			break;+		default:+			dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);+			error = EINVAL;+			goto bail;+		}++		if (info.blocksize) {+			crie.cri_alg = sop.cipher;+			crie.cri_klen = sop.keylen * 8;+			if ((info.maxkey && sop.keylen > info.maxkey) ||+				   	sop.keylen < info.minkey) {+				dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);+				error = EINVAL;+				goto bail;+			}++			crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);+			if (copy_from_user(crie.cri_key, sop.key,+							crie.cri_klen/8)) {+				dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);+				error = EFAULT;+				goto bail;+			}+			if (info.authsize)+				crie.cri_next = &cria;+		}++		if (info.authsize) {+			cria.cri_alg = sop.mac;+			cria.cri_klen = sop.mackeylen * 8;+			if (info.authkey && sop.mackeylen != info.authkey) {+				dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,+						CIOCGSESSSTR, sop.mackeylen, info.authkey);+				error = EINVAL;+				goto bail;+			}++			if (cria.cri_klen) {+				cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);+				if (copy_from_user(cria.cri_key, sop.mackey,+								cria.cri_klen / 8)) {+					dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);+					error = EFAULT;+					goto bail;+				}+			}+		}++		/* NB: CIOGSESSION2 has the crid */+		if (cmd == CIOCGSESSION2) {+			crid = sop.crid;+			error = checkcrid(crid);+			if (error) {+				dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,+						CIOCGSESSSTR, error);+				goto bail;+			}+		} else {+			/* allow either HW or SW to be used */+			crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;+		}+		error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);+		if (error) {+			dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);+			goto bail;+		}++		cse = csecreate(fcr, sid, &crie, &cria, &info);+		if (cse == NULL) {+			crypto_freesession(sid);+			error = EINVAL;+			dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);+			goto bail;+		}+		sop.ses = cse->ses;++		if (cmd == CIOCGSESSION2) {+			/* return hardware/driver id */+			sop.crid = CRYPTO_SESID2HID(cse->sid);+		}++		if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?+					sizeof(struct session_op) : sizeof(sop))) {+			dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);+			error = EFAULT;+		}+bail:+		if (error) {+			dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);+			if (crie.cri_key)+				kfree(crie.cri_key);+			if (cria.cri_key)+				kfree(cria.cri_key);+		}+		break;+	case CIOCFSESSION:+		dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);+		get_user(ses, (uint32_t*)arg);+		cse = csefind(fcr, ses);+		if (cse == NULL) {+			error = EINVAL;+			dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);+			break;+		}+		csedelete(fcr, cse);+		error = csefree(cse);+		break;+	case CIOCCRYPT:+		dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);+		if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {+			dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);+			error = EFAULT;+			goto bail;+		}+		cse = csefind(fcr, cop.ses);+		if (cse == NULL) {+			error = EINVAL;+			dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);+			break;+		}+		error = cryptodev_op(cse, &cop);+		if(copy_to_user((void*)arg, &cop, sizeof(cop))) {+			dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);+			error = EFAULT;+			goto bail;+		}+		break;+	case CIOCKEY:+	case CIOCKEY2:+		dprintk("%s(CIOCKEY)\n", __FUNCTION__);+		if (!crypto_userasymcrypto)+			return (EPERM);		/* XXX compat? */+		if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {+			dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);+			error = EFAULT;+			goto bail;+		}+		if (cmd == CIOCKEY) {+			/* NB: crypto core enforces s/w driver use */+			kop.crk_crid =+			    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;+		}+		error = cryptodev_key(&kop);+		if(copy_to_user((void*)arg, &kop, sizeof(kop))) {+			dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);+			error = EFAULT;+			goto bail;+		}+		break;+	case CIOCASYMFEAT:+		dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);+		if (!crypto_userasymcrypto) {+			/*+			 * NB: if user asym crypto operations are+			 * not permitted return "no algorithms"+			 * so well-behaved applications will just+			 * fallback to doing them in software.+			 */+			feat = 0;+		} else+			error = crypto_getfeat(&feat);+		if (!error) {+		  error = copy_to_user((void*)arg, &feat, sizeof(feat));+		}+		break;+	case CIOCFINDDEV:+		if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {+			dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);+			error = EFAULT;+			goto bail;+		}+		error = cryptodev_find(&fop);+		if (copy_to_user((void*)arg, &fop, sizeof(fop))) {+			dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);+			error = EFAULT;+			goto bail;+		}+		break;+	default:+		dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);+		error = EINVAL;+		break;+	}+	return(-error);+}++#ifdef HAVE_UNLOCKED_IOCTL+static long+cryptodev_unlocked_ioctl(+	struct file *filp,+	unsigned int cmd,+	unsigned long arg)+{+	return cryptodev_ioctl(NULL, filp, cmd, arg);+}+#endif++static int+cryptodev_open(struct inode *inode, struct file *filp)+{+	struct fcrypt *fcr;++	dprintk("%s()\n", __FUNCTION__);+	if (filp->private_data) {+		printk("cryptodev: Private data already exists !\n");+		return(0);+	}++	fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);+	if (!fcr) {+		dprintk("%s() - malloc failed\n", __FUNCTION__);+		return(-ENOMEM);+	}+	memset(fcr, 0, sizeof(*fcr));++	INIT_LIST_HEAD(&fcr->csessions);+	filp->private_data = fcr;+	return(0);+}++static int+cryptodev_release(struct inode *inode, struct file *filp)+{+	struct fcrypt *fcr = filp->private_data;+	struct csession *cse, *tmp;++	dprintk("%s()\n", __FUNCTION__);+	if (!filp) {+		printk("cryptodev: No private data on release\n");+		return(0);+	}++	list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {+		list_del(&cse->list);+		(void)csefree(cse);+	}+	filp->private_data = NULL;+	kfree(fcr);+	return(0);+}++static struct file_operations cryptodev_fops = {+	.owner = THIS_MODULE,+	.open = cryptodev_open,+	.release = cryptodev_release,+#ifdef HAVE_UNLOCKED_IOCTL+	.unlocked_ioctl = cryptodev_unlocked_ioctl,+#endif+};++static struct miscdevice cryptodev = {+	.minor = CRYPTODEV_MINOR,+	.name = "crypto",+	.fops = &cryptodev_fops,+};++static int __init+cryptodev_init(void)+{+	int rc;++	dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);+	rc = misc_register(&cryptodev);+	if (rc) {+		printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");+		return(rc);+	}++	return(0);+}++static void __exit+cryptodev_exit(void)+{+	dprintk("%s()\n", __FUNCTION__);+	misc_deregister(&cryptodev);+}++module_init(cryptodev_init);+module_exit(cryptodev_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");diff -Nur linux-2.6.36.orig/crypto/ocf/cryptodev.h linux-2.6.36/crypto/ocf/cryptodev.h--- linux-2.6.36.orig/crypto/ocf/cryptodev.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/cryptodev.h	2010-11-09 20:28:04.492495480 +0100@@ -0,0 +1,479 @@+/*	$FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $	*/+/*	$OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $	*/++/*-+ * Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ * The license and original author are listed below.+ *+ * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)+ * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting+ *+ * This code was written by Angelos D. Keromytis in Athens, Greece, in+ * February 2000. Network Security Technologies Inc. (NSTI) kindly+ * supported the development of this code.+ *+ * Copyright (c) 2000 Angelos D. Keromytis+ *+ * Permission to use, copy, and modify this software with or without fee+ * is hereby granted, provided that this entire notice is included in+ * all source code copies of any software which is or includes a copy or+ * modification of this software.+ *+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR+ * PURPOSE.+ *+ * Copyright (c) 2001 Theo de Raadt+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+ */++#ifndef _CRYPTO_CRYPTO_H_+#define _CRYPTO_CRYPTO_H_++/* Some initial values */+#define CRYPTO_DRIVERS_INITIAL	4+#define CRYPTO_SW_SESSIONS	32++/* Hash values */+#define NULL_HASH_LEN		0+#define MD5_HASH_LEN		16+#define SHA1_HASH_LEN		20+#define RIPEMD160_HASH_LEN	20+#define SHA2_256_HASH_LEN	32+#define SHA2_384_HASH_LEN	48+#define SHA2_512_HASH_LEN	64+#define MD5_KPDK_HASH_LEN	16+#define SHA1_KPDK_HASH_LEN	20+/* Maximum hash algorithm result length */+#define HASH_MAX_LEN		SHA2_512_HASH_LEN /* Keep this updated */++/* HMAC values */+#define NULL_HMAC_BLOCK_LEN			1+#define MD5_HMAC_BLOCK_LEN			64+#define SHA1_HMAC_BLOCK_LEN			64+#define RIPEMD160_HMAC_BLOCK_LEN	64+#define SHA2_256_HMAC_BLOCK_LEN		64+#define SHA2_384_HMAC_BLOCK_LEN		128+#define SHA2_512_HMAC_BLOCK_LEN		128+/* Maximum HMAC block length */+#define HMAC_MAX_BLOCK_LEN		SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */+#define HMAC_IPAD_VAL			0x36+#define HMAC_OPAD_VAL			0x5C++/* Encryption algorithm block sizes */+#define NULL_BLOCK_LEN			1+#define DES_BLOCK_LEN			8+#define DES3_BLOCK_LEN			8+#define BLOWFISH_BLOCK_LEN		8+#define SKIPJACK_BLOCK_LEN		8+#define CAST128_BLOCK_LEN		8+#define RIJNDAEL128_BLOCK_LEN	16+#define AES_BLOCK_LEN			RIJNDAEL128_BLOCK_LEN+#define CAMELLIA_BLOCK_LEN		16+#define ARC4_BLOCK_LEN			1+#define EALG_MAX_BLOCK_LEN		AES_BLOCK_LEN /* Keep this updated */++/* Encryption algorithm min and max key sizes */+#define NULL_MIN_KEY_LEN		0+#define NULL_MAX_KEY_LEN		0+#define DES_MIN_KEY_LEN			8+#define DES_MAX_KEY_LEN			8+#define DES3_MIN_KEY_LEN		24+#define DES3_MAX_KEY_LEN		24+#define BLOWFISH_MIN_KEY_LEN	4+#define BLOWFISH_MAX_KEY_LEN	56+#define SKIPJACK_MIN_KEY_LEN	10+#define SKIPJACK_MAX_KEY_LEN	10+#define CAST128_MIN_KEY_LEN		5+#define CAST128_MAX_KEY_LEN		16+#define RIJNDAEL128_MIN_KEY_LEN	16+#define RIJNDAEL128_MAX_KEY_LEN	32+#define AES_MIN_KEY_LEN			RIJNDAEL128_MIN_KEY_LEN+#define AES_MAX_KEY_LEN			RIJNDAEL128_MAX_KEY_LEN+#define CAMELLIA_MIN_KEY_LEN	16+#define CAMELLIA_MAX_KEY_LEN	32+#define ARC4_MIN_KEY_LEN		1+#define ARC4_MAX_KEY_LEN		256++/* Max size of data that can be processed */+#define CRYPTO_MAX_DATA_LEN		64*1024 - 1++#define CRYPTO_ALGORITHM_MIN	1+#define CRYPTO_DES_CBC			1+#define CRYPTO_3DES_CBC			2+#define CRYPTO_BLF_CBC			3+#define CRYPTO_CAST_CBC			4+#define CRYPTO_SKIPJACK_CBC		5+#define CRYPTO_MD5_HMAC			6+#define CRYPTO_SHA1_HMAC		7+#define CRYPTO_RIPEMD160_HMAC	8+#define CRYPTO_MD5_KPDK			9+#define CRYPTO_SHA1_KPDK		10+#define CRYPTO_RIJNDAEL128_CBC	11 /* 128 bit blocksize */+#define CRYPTO_AES_CBC			11 /* 128 bit blocksize -- the same as above */+#define CRYPTO_ARC4				12+#define CRYPTO_MD5				13+#define CRYPTO_SHA1				14+#define CRYPTO_NULL_HMAC		15+#define CRYPTO_NULL_CBC			16+#define CRYPTO_DEFLATE_COMP		17 /* Deflate compression algorithm */+#define CRYPTO_SHA2_256_HMAC	18+#define CRYPTO_SHA2_384_HMAC	19+#define CRYPTO_SHA2_512_HMAC	20+#define CRYPTO_CAMELLIA_CBC		21+#define CRYPTO_SHA2_256			22+#define CRYPTO_SHA2_384			23+#define CRYPTO_SHA2_512			24+#define CRYPTO_RIPEMD160		25+#define CRYPTO_ALGORITHM_MAX	25 /* Keep updated - see below */++/* Algorithm flags */+#define CRYPTO_ALG_FLAG_SUPPORTED	0x01 /* Algorithm is supported */+#define CRYPTO_ALG_FLAG_RNG_ENABLE	0x02 /* Has HW RNG for DH/DSA */+#define CRYPTO_ALG_FLAG_DSA_SHA		0x04 /* Can do SHA on msg */++/*+ * Crypto driver/device flags.  They can set in the crid+ * parameter when creating a session or submitting a key+ * op to affect the device/driver assigned.  If neither+ * of these are specified then the crid is assumed to hold+ * the driver id of an existing (and suitable) device that+ * must be used to satisfy the request.+ */+#define CRYPTO_FLAG_HARDWARE	0x01000000	/* hardware accelerated */+#define CRYPTO_FLAG_SOFTWARE	0x02000000	/* software implementation */++/* NB: deprecated */+struct session_op {+	u_int32_t	cipher;		/* ie. CRYPTO_DES_CBC */+	u_int32_t	mac;		/* ie. CRYPTO_MD5_HMAC */++	u_int32_t	keylen;		/* cipher key */+	caddr_t		key;+	int		mackeylen;	/* mac key */+	caddr_t		mackey;++  	u_int32_t	ses;		/* returns: session # */ +};++struct session2_op {+	u_int32_t	cipher;		/* ie. CRYPTO_DES_CBC */+	u_int32_t	mac;		/* ie. CRYPTO_MD5_HMAC */++	u_int32_t	keylen;		/* cipher key */+	caddr_t		key;+	int		mackeylen;	/* mac key */+	caddr_t		mackey;++  	u_int32_t	ses;		/* returns: session # */ +	int		crid;		/* driver id + flags (rw) */+	int		pad[4];		/* for future expansion */+};++struct crypt_op {+	u_int32_t	ses;+	u_int16_t	op;		/* i.e. COP_ENCRYPT */+#define COP_NONE	0+#define COP_ENCRYPT	1+#define COP_DECRYPT	2+	u_int16_t	flags;+#define	COP_F_BATCH	0x0008		/* Batch op if possible */+	u_int		len;+	caddr_t		src, dst;	/* become iov[] inside kernel */+	caddr_t		mac;		/* must be big enough for chosen MAC */+	caddr_t		iv;+};++/*+ * Parameters for looking up a crypto driver/device by+ * device name or by id.  The latter are returned for+ * created sessions (crid) and completed key operations.+ */+struct crypt_find_op {+	int		crid;		/* driver id + flags */+	char		name[32];	/* device/driver name */+};++/* bignum parameter, in packed bytes, ... */+struct crparam {+	caddr_t		crp_p;+	u_int		crp_nbits;+};++#define CRK_MAXPARAM	8++struct crypt_kop {+	u_int		crk_op;		/* ie. CRK_MOD_EXP or other */+	u_int		crk_status;	/* return status */+	u_short		crk_iparams;	/* # of input parameters */+	u_short		crk_oparams;	/* # of output parameters */+	u_int		crk_crid;	/* NB: only used by CIOCKEY2 (rw) */+	struct crparam	crk_param[CRK_MAXPARAM];+};+#define CRK_ALGORITM_MIN	0+#define CRK_MOD_EXP		0+#define CRK_MOD_EXP_CRT		1+#define CRK_DSA_SIGN		2+#define CRK_DSA_VERIFY		3+#define CRK_DH_COMPUTE_KEY	4+#define CRK_ALGORITHM_MAX	4 /* Keep updated - see below */++#define CRF_MOD_EXP		(1 << CRK_MOD_EXP)+#define CRF_MOD_EXP_CRT		(1 << CRK_MOD_EXP_CRT)+#define CRF_DSA_SIGN		(1 << CRK_DSA_SIGN)+#define CRF_DSA_VERIFY		(1 << CRK_DSA_VERIFY)+#define CRF_DH_COMPUTE_KEY	(1 << CRK_DH_COMPUTE_KEY)++/*+ * done against open of /dev/crypto, to get a cloned descriptor.+ * Please use F_SETFD against the cloned descriptor.+ */+#define CRIOGET		_IOWR('c', 100, u_int32_t)+#define CRIOASYMFEAT	CIOCASYMFEAT+#define CRIOFINDDEV	CIOCFINDDEV++/* the following are done against the cloned descriptor */+#define CIOCGSESSION	_IOWR('c', 101, struct session_op)+#define CIOCFSESSION	_IOW('c', 102, u_int32_t)+#define CIOCCRYPT	_IOWR('c', 103, struct crypt_op)+#define CIOCKEY		_IOWR('c', 104, struct crypt_kop)+#define CIOCASYMFEAT	_IOR('c', 105, u_int32_t)+#define CIOCGSESSION2	_IOWR('c', 106, struct session2_op)+#define CIOCKEY2	_IOWR('c', 107, struct crypt_kop)+#define CIOCFINDDEV	_IOWR('c', 108, struct crypt_find_op)++struct cryptotstat {+	struct timespec	acc;		/* total accumulated time */+	struct timespec	min;		/* min time */+	struct timespec	max;		/* max time */+	u_int32_t	count;		/* number of observations */+};++struct cryptostats {+	u_int32_t	cs_ops;		/* symmetric crypto ops submitted */+	u_int32_t	cs_errs;	/* symmetric crypto ops that failed */+	u_int32_t	cs_kops;	/* asymetric/key ops submitted */+	u_int32_t	cs_kerrs;	/* asymetric/key ops that failed */+	u_int32_t	cs_intrs;	/* crypto swi thread activations */+	u_int32_t	cs_rets;	/* crypto return thread activations */+	u_int32_t	cs_blocks;	/* symmetric op driver block */+	u_int32_t	cs_kblocks;	/* symmetric op driver block */+	/*+	 * When CRYPTO_TIMING is defined at compile time and the+	 * sysctl debug.crypto is set to 1, the crypto system will+	 * accumulate statistics about how long it takes to process+	 * crypto requests at various points during processing.+	 */+	struct cryptotstat cs_invoke;	/* crypto_dipsatch -> crypto_invoke */+	struct cryptotstat cs_done;	/* crypto_invoke -> crypto_done */+	struct cryptotstat cs_cb;	/* crypto_done -> callback */+	struct cryptotstat cs_finis;	/* callback -> callback return */++	u_int32_t	cs_drops;		/* crypto ops dropped due to congestion */+};++#ifdef __KERNEL__++/* Standard initialization structure beginning */+struct cryptoini {+	int		cri_alg;	/* Algorithm to use */+	int		cri_klen;	/* Key length, in bits */+	int		cri_mlen;	/* Number of bytes we want from the+					   entire hash. 0 means all. */+	caddr_t		cri_key;	/* key to use */+	u_int8_t	cri_iv[EALG_MAX_BLOCK_LEN];	/* IV to use */+	struct cryptoini *cri_next;+};++/* Describe boundaries of a single crypto operation */+struct cryptodesc {+	int		crd_skip;	/* How many bytes to ignore from start */+	int		crd_len;	/* How many bytes to process */+	int		crd_inject;	/* Where to inject results, if applicable */+	int		crd_flags;++#define CRD_F_ENCRYPT		0x01	/* Set when doing encryption */+#define CRD_F_IV_PRESENT	0x02	/* When encrypting, IV is already in+					   place, so don't copy. */+#define CRD_F_IV_EXPLICIT	0x04	/* IV explicitly provided */+#define CRD_F_DSA_SHA_NEEDED	0x08	/* Compute SHA-1 of buffer for DSA */+#define CRD_F_KEY_EXPLICIT	0x10	/* Key explicitly provided */+#define CRD_F_COMP		0x0f    /* Set when doing compression */++	struct cryptoini	CRD_INI; /* Initialization/context data */+#define crd_iv		CRD_INI.cri_iv+#define crd_key		CRD_INI.cri_key+#define crd_alg		CRD_INI.cri_alg+#define crd_klen	CRD_INI.cri_klen+#define crd_mlen	CRD_INI.cri_mlen++	struct cryptodesc *crd_next;+};++/* Structure describing complete operation */+struct cryptop {+	struct list_head crp_next;+	wait_queue_head_t crp_waitq;++	u_int64_t	crp_sid;	/* Session ID */+	int		crp_ilen;	/* Input data total length */+	int		crp_olen;	/* Result total length */++	int		crp_etype;	/*+					 * Error type (zero means no error).+					 * All error codes except EAGAIN+					 * indicate possible data corruption (as in,+					 * the data have been touched). On all+					 * errors, the crp_sid may have changed+					 * (reset to a new one), so the caller+					 * should always check and use the new+					 * value on future requests.+					 */+	int		crp_flags;++#define CRYPTO_F_SKBUF		0x0001	/* Input/output are skbuf chains */+#define CRYPTO_F_IOV		0x0002	/* Input/output are uio */+#define CRYPTO_F_REL		0x0004	/* Must return data in same place */+#define CRYPTO_F_BATCH		0x0008	/* Batch op if possible */+#define CRYPTO_F_CBIMM		0x0010	/* Do callback immediately */+#define CRYPTO_F_DONE		0x0020	/* Operation completed */+#define CRYPTO_F_CBIFSYNC	0x0040	/* Do CBIMM if op is synchronous */++	caddr_t		crp_buf;	/* Data to be processed */+	caddr_t		crp_opaque;	/* Opaque pointer, passed along */+	struct cryptodesc *crp_desc;	/* Linked list of processing descriptors */++	int (*crp_callback)(struct cryptop *); /* Callback function */+};++#define CRYPTO_BUF_CONTIG	0x0+#define CRYPTO_BUF_IOV		0x1+#define CRYPTO_BUF_SKBUF		0x2++#define CRYPTO_OP_DECRYPT	0x0+#define CRYPTO_OP_ENCRYPT	0x1++/*+ * Hints passed to process methods.+ */+#define CRYPTO_HINT_MORE	0x1	/* more ops coming shortly */++struct cryptkop {+	struct list_head krp_next;+	wait_queue_head_t krp_waitq;++	int		krp_flags;+#define CRYPTO_KF_DONE		0x0001	/* Operation completed */+#define CRYPTO_KF_CBIMM		0x0002	/* Do callback immediately */++	u_int		krp_op;		/* ie. CRK_MOD_EXP or other */+	u_int		krp_status;	/* return status */+	u_short		krp_iparams;	/* # of input parameters */+	u_short		krp_oparams;	/* # of output parameters */+	u_int		krp_crid;	/* desired device, etc. */+	u_int32_t	krp_hid;+	struct crparam	krp_param[CRK_MAXPARAM];	/* kvm */+	int		(*krp_callback)(struct cryptkop *);+};++#include <ocf-compat.h>++/*+ * Session ids are 64 bits.  The lower 32 bits contain a "local id" which+ * is a driver-private session identifier.  The upper 32 bits contain a+ * "hardware id" used by the core crypto code to identify the driver and+ * a copy of the driver's capabilities that can be used by client code to+ * optimize operation.+ */+#define CRYPTO_SESID2HID(_sid)	(((_sid) >> 32) & 0x00ffffff)+#define CRYPTO_SESID2CAPS(_sid)	(((_sid) >> 32) & 0xff000000)+#define CRYPTO_SESID2LID(_sid)	(((u_int32_t) (_sid)) & 0xffffffff)++extern	int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);+extern	int crypto_freesession(u_int64_t sid);+#define CRYPTOCAP_F_HARDWARE	CRYPTO_FLAG_HARDWARE+#define CRYPTOCAP_F_SOFTWARE	CRYPTO_FLAG_SOFTWARE+#define CRYPTOCAP_F_SYNC	0x04000000	/* operates synchronously */+extern	int32_t crypto_get_driverid(device_t dev, int flags);+extern	int crypto_find_driver(const char *);+extern	device_t crypto_find_device_byhid(int hid);+extern	int crypto_getcaps(int hid);+extern	int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,+	    u_int32_t flags);+extern	int crypto_kregister(u_int32_t, int, u_int32_t);+extern	int crypto_unregister(u_int32_t driverid, int alg);+extern	int crypto_unregister_all(u_int32_t driverid);+extern	int crypto_dispatch(struct cryptop *crp);+extern	int crypto_kdispatch(struct cryptkop *);+#define CRYPTO_SYMQ	0x1+#define CRYPTO_ASYMQ	0x2+extern	int crypto_unblock(u_int32_t, int);+extern	void crypto_done(struct cryptop *crp);+extern	void crypto_kdone(struct cryptkop *);+extern	int crypto_getfeat(int *);++extern	void crypto_freereq(struct cryptop *crp);+extern	struct cryptop *crypto_getreq(int num);++extern  int crypto_usercrypto;      /* userland may do crypto requests */+extern  int crypto_userasymcrypto;  /* userland may do asym crypto reqs */+extern  int crypto_devallowsoft;    /* only use hardware crypto */++/*+ * random number support,  crypto_unregister_all will unregister+ */+extern int crypto_rregister(u_int32_t driverid,+		int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);+extern int crypto_runregister_all(u_int32_t driverid);++/*+ * Crypto-related utility routines used mainly by drivers.+ *+ * XXX these don't really belong here; but for now they're+ *     kept apart from the rest of the system.+ */+struct uio;+extern	void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);+extern	void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);+extern	struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);++extern	void crypto_copyback(int flags, caddr_t buf, int off, int size,+	    caddr_t in);+extern	void crypto_copydata(int flags, caddr_t buf, int off, int size,+	    caddr_t out);+extern	int crypto_apply(int flags, caddr_t buf, int off, int len,+	    int (*f)(void *, void *, u_int), void *arg);++#endif /* __KERNEL__ */+#endif /* _CRYPTO_CRYPTO_H_ */diff -Nur linux-2.6.36.orig/crypto/ocf/cryptosoft.c linux-2.6.36/crypto/ocf/cryptosoft.c--- linux-2.6.36.orig/crypto/ocf/cryptosoft.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/cryptosoft.c	2010-11-09 20:28:04.532495450 +0100@@ -0,0 +1,1210 @@+/*+ * An OCF module that uses the linux kernel cryptoapi, based on the+ * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)+ * but is mostly unrecognisable,+ *+ * Written by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2004-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this product+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ * ---------------------------------------------------------------------------+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/sched.h>+#include <linux/wait.h>+#include <linux/crypto.h>+#include <linux/mm.h>+#include <linux/skbuff.h>+#include <linux/random.h>+#include <linux/version.h>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)+#include <linux/scatterlist.h>+#endif+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)+#include <crypto/hash.h>+#endif++#include <cryptodev.h>+#include <uio.h>++struct {+	softc_device_decl	sc_dev;+} swcr_softc;++#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)++#define SW_TYPE_CIPHER		0x01+#define SW_TYPE_HMAC		0x02+#define SW_TYPE_HASH		0x04+#define SW_TYPE_COMP		0x08+#define SW_TYPE_BLKCIPHER	0x10+#define SW_TYPE_ALG_MASK	0x1f++#define SW_TYPE_ASYNC		0x8000++/* We change some of the above if we have an async interface */++#define SW_TYPE_ALG_AMASK	(SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)++#define SW_TYPE_ABLKCIPHER	(SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)+#define SW_TYPE_AHASH		(SW_TYPE_HASH | SW_TYPE_ASYNC)+#define SW_TYPE_AHMAC		(SW_TYPE_HMAC | SW_TYPE_ASYNC)++#define SCATTERLIST_MAX 16++struct swcr_data {+	int					sw_type;+	int					sw_alg;+	struct crypto_tfm	*sw_tfm;+	union {+		struct {+			char *sw_key;+			int  sw_klen;+			int  sw_mlen;+		} hmac;+		void *sw_comp_buf;+	} u;+	struct swcr_data	*sw_next;+};++struct swcr_req {+	struct swcr_data	*sw_head;+	struct swcr_data	*sw;+	struct cryptop		*crp;+	struct cryptodesc	*crd;+	struct scatterlist	 sg[SCATTERLIST_MAX];+	unsigned char		 iv[EALG_MAX_BLOCK_LEN];+	char				 result[HASH_MAX_LEN];+	void				*crypto_req;+};++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)+static kmem_cache_t *swcr_req_cache;+#else+static struct kmem_cache *swcr_req_cache;+#endif++#ifndef CRYPTO_TFM_MODE_CBC+/*+ * As of linux-2.6.21 this is no longer defined, and presumably no longer+ * needed to be passed into the crypto core code.+ */+#define	CRYPTO_TFM_MODE_CBC	0+#define	CRYPTO_TFM_MODE_ECB	0+#endif++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+	/*+	 * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new+	 * API into old API.+	 */++	/* Symmetric/Block Cipher */+	struct blkcipher_desc+	{+		struct crypto_tfm *tfm;+		void *info;+	};+	#define ecb(X)								#X , CRYPTO_TFM_MODE_ECB+	#define cbc(X)								#X , CRYPTO_TFM_MODE_CBC+	#define crypto_has_blkcipher(X, Y, Z)		crypto_alg_available(X, 0)+	#define crypto_blkcipher_cast(X)			X+	#define crypto_blkcipher_tfm(X)				X+	#define crypto_alloc_blkcipher(X, Y, Z)		crypto_alloc_tfm(X, mode)+	#define crypto_blkcipher_ivsize(X)			crypto_tfm_alg_ivsize(X)+	#define crypto_blkcipher_blocksize(X)		crypto_tfm_alg_blocksize(X)+	#define crypto_blkcipher_setkey(X, Y, Z)	crypto_cipher_setkey(X, Y, Z)+	#define crypto_blkcipher_encrypt_iv(W, X, Y, Z)	\+				crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))+	#define crypto_blkcipher_decrypt_iv(W, X, Y, Z)	\+				crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))+	#define crypto_blkcipher_set_flags(x, y)	/* nop */++	/* Hash/HMAC/Digest */+	struct hash_desc+	{+		struct crypto_tfm *tfm;+	};+	#define hmac(X)							#X , 0+	#define crypto_has_hash(X, Y, Z)		crypto_alg_available(X, 0)+	#define crypto_hash_cast(X)				X+	#define crypto_hash_tfm(X)				X+	#define crypto_alloc_hash(X, Y, Z)		crypto_alloc_tfm(X, mode)+	#define crypto_hash_digestsize(X)		crypto_tfm_alg_digestsize(X)+	#define crypto_hash_digest(W, X, Y, Z)	\+				crypto_digest_digest((W)->tfm, X, sg_num, Z)++	/* Asymmetric Cipher */+	#define crypto_has_cipher(X, Y, Z)		crypto_alg_available(X, 0)++	/* Compression */+	#define crypto_has_comp(X, Y, Z)		crypto_alg_available(X, 0)+	#define crypto_comp_tfm(X)				X+	#define crypto_comp_cast(X)				X+	#define crypto_alloc_comp(X, Y, Z)		crypto_alloc_tfm(X, mode)+	#define plain(X)	#X , 0+#else+	#define ecb(X)	"ecb(" #X ")" , 0+	#define cbc(X)	"cbc(" #X ")" , 0+	#define hmac(X)	"hmac(" #X ")" , 0+	#define plain(X)	#X , 0+#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)+/* no ablkcipher in older kernels */+#define crypto_alloc_ablkcipher(a,b,c)		(NULL)+#define crypto_ablkcipher_tfm(x)			((struct crypto_tfm *)(x))+#define crypto_ablkcipher_set_flags(a, b)	/* nop */+#define crypto_ablkcipher_setkey(x, y, z)	(-EINVAL)+#define	crypto_has_ablkcipher(a,b,c)		(0)+#else+#define	HAVE_ABLKCIPHER+#endif++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)+/* no ahash in older kernels */+#define crypto_ahash_tfm(x)					((struct crypto_tfm *)(x))+#define	crypto_alloc_ahash(a,b,c)			(NULL)+#define	crypto_ahash_digestsize(x)			0+#else+#define	HAVE_AHASH+#endif++struct crypto_details {+	char *alg_name;+	int mode;+	int sw_type;+};++static struct crypto_details crypto_details[] = {+	[CRYPTO_DES_CBC]         = { cbc(des),          SW_TYPE_BLKCIPHER, },+	[CRYPTO_3DES_CBC]        = { cbc(des3_ede),     SW_TYPE_BLKCIPHER, },+	[CRYPTO_BLF_CBC]         = { cbc(blowfish),     SW_TYPE_BLKCIPHER, },+	[CRYPTO_CAST_CBC]        = { cbc(cast5),        SW_TYPE_BLKCIPHER, },+	[CRYPTO_SKIPJACK_CBC]    = { cbc(skipjack),     SW_TYPE_BLKCIPHER, },+	[CRYPTO_MD5_HMAC]        = { hmac(md5),         SW_TYPE_HMAC, },+	[CRYPTO_SHA1_HMAC]       = { hmac(sha1),        SW_TYPE_HMAC, },+	[CRYPTO_RIPEMD160_HMAC]  = { hmac(ripemd160),   SW_TYPE_HMAC, },+	[CRYPTO_MD5_KPDK]        = { plain(md5-kpdk),   SW_TYPE_HASH, },+	[CRYPTO_SHA1_KPDK]       = { plain(sha1-kpdk),  SW_TYPE_HASH, },+	[CRYPTO_AES_CBC]         = { cbc(aes),          SW_TYPE_BLKCIPHER, },+	[CRYPTO_ARC4]            = { ecb(arc4),         SW_TYPE_BLKCIPHER, },+	[CRYPTO_MD5]             = { plain(md5),        SW_TYPE_HASH, },+	[CRYPTO_SHA1]            = { plain(sha1),       SW_TYPE_HASH, },+	[CRYPTO_NULL_HMAC]       = { hmac(digest_null), SW_TYPE_HMAC, },+	[CRYPTO_NULL_CBC]        = { cbc(cipher_null),  SW_TYPE_BLKCIPHER, },+	[CRYPTO_DEFLATE_COMP]    = { plain(deflate),    SW_TYPE_COMP, },+	[CRYPTO_SHA2_256_HMAC]   = { hmac(sha256),      SW_TYPE_HMAC, },+	[CRYPTO_SHA2_384_HMAC]   = { hmac(sha384),      SW_TYPE_HMAC, },+	[CRYPTO_SHA2_512_HMAC]   = { hmac(sha512),      SW_TYPE_HMAC, },+	[CRYPTO_CAMELLIA_CBC]    = { cbc(camellia),     SW_TYPE_BLKCIPHER, },+	[CRYPTO_SHA2_256]        = { plain(sha256),     SW_TYPE_HASH, },+	[CRYPTO_SHA2_384]        = { plain(sha384),     SW_TYPE_HASH, },+	[CRYPTO_SHA2_512]        = { plain(sha512),     SW_TYPE_HASH, },+	[CRYPTO_RIPEMD160]       = { plain(ripemd160),  SW_TYPE_HASH, },+};++int32_t swcr_id = -1;+module_param(swcr_id, int, 0444);+MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");++int swcr_fail_if_compression_grows = 1;+module_param(swcr_fail_if_compression_grows, int, 0644);+MODULE_PARM_DESC(swcr_fail_if_compression_grows,+                "Treat compression that results in more data as a failure");++int swcr_no_ahash = 0;+module_param(swcr_no_ahash, int, 0644);+MODULE_PARM_DESC(swcr_no_ahash,+                "Do not use async hash/hmac even if available");++int swcr_no_ablk = 0;+module_param(swcr_no_ablk, int, 0644);+MODULE_PARM_DESC(swcr_no_ablk,+                "Do not use async blk ciphers even if available");++static struct swcr_data **swcr_sessions = NULL;+static u_int32_t swcr_sesnum = 0;++static	int swcr_process(device_t, struct cryptop *, int);+static	int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);+static	int swcr_freesession(device_t, u_int64_t);++static device_method_t swcr_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	swcr_newsession),+	DEVMETHOD(cryptodev_freesession,swcr_freesession),+	DEVMETHOD(cryptodev_process,	swcr_process),+};++#define debug swcr_debug+int swcr_debug = 0;+module_param(swcr_debug, int, 0644);+MODULE_PARM_DESC(swcr_debug, "Enable debug");++static void swcr_process_req(struct swcr_req *req);++/*+ * Generate a new software session.+ */+static int+swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)+{+	struct swcr_data **swd;+	u_int32_t i;+	int error;+	char *algo;+	int mode;++	dprintk("%s()\n", __FUNCTION__);+	if (sid == NULL || cri == NULL) {+		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	if (swcr_sessions) {+		for (i = 1; i < swcr_sesnum; i++)+			if (swcr_sessions[i] == NULL)+				break;+	} else+		i = 1;		/* NB: to silence compiler warning */++	if (swcr_sessions == NULL || i == swcr_sesnum) {+		if (swcr_sessions == NULL) {+			i = 1; /* We leave swcr_sessions[0] empty */+			swcr_sesnum = CRYPTO_SW_SESSIONS;+		} else+			swcr_sesnum *= 2;++		swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);+		if (swd == NULL) {+			/* Reset session number */+			if (swcr_sesnum == CRYPTO_SW_SESSIONS)+				swcr_sesnum = 0;+			else+				swcr_sesnum /= 2;+			dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+			return ENOBUFS;+		}+		memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));++		/* Copy existing sessions */+		if (swcr_sessions) {+			memcpy(swd, swcr_sessions,+			    (swcr_sesnum / 2) * sizeof(struct swcr_data *));+			kfree(swcr_sessions);+		}++		swcr_sessions = swd;+	}++	swd = &swcr_sessions[i];+	*sid = i;++	while (cri) {+		*swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),+				SLAB_ATOMIC);+		if (*swd == NULL) {+			swcr_freesession(NULL, i);+			dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+			return ENOBUFS;+		}+		memset(*swd, 0, sizeof(struct swcr_data));++		if (cri->cri_alg < 0 ||+				cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){+			printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);+			swcr_freesession(NULL, i);+			return EINVAL;+		}++		algo = crypto_details[cri->cri_alg].alg_name;+		if (!algo || !*algo) {+			printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);+			swcr_freesession(NULL, i);+			return EINVAL;+		}++		mode = crypto_details[cri->cri_alg].mode;+		(*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;+		(*swd)->sw_alg = cri->cri_alg;++		/* Algorithm specific configuration */+		switch (cri->cri_alg) {+		case CRYPTO_NULL_CBC:+			cri->cri_klen = 0; /* make it work with crypto API */+			break;+		default:+			break;+		}++		if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {+			dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,+					algo, mode);++			/* try async first */+			(*swd)->sw_tfm = swcr_no_ablk ? NULL :+					crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));+			if ((*swd)->sw_tfm) {+				dprintk("%s %s cipher is async\n", __FUNCTION__, algo);+				(*swd)->sw_type |= SW_TYPE_ASYNC;+			} else {+				dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);+				(*swd)->sw_tfm = crypto_blkcipher_tfm(+						crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));+			}+			if (!(*swd)->sw_tfm) {+				dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",+						algo,mode);+				swcr_freesession(NULL, i);+				return EINVAL;+			}++			if (debug) {+				dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",+						__FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);+				for (i = 0; i < (cri->cri_klen + 7) / 8; i++)+					dprintk("%s0x%x", (i % 8) ? " " : "\n    ",+							cri->cri_key[i] & 0xff);+				dprintk("\n");+			}+			if ((*swd)->sw_type & SW_TYPE_ASYNC) {+				/* OCF doesn't enforce keys */+				crypto_ablkcipher_set_flags(+						__crypto_ablkcipher_cast((*swd)->sw_tfm),+							CRYPTO_TFM_REQ_WEAK_KEY);+				error = crypto_ablkcipher_setkey(+							__crypto_ablkcipher_cast((*swd)->sw_tfm),+								cri->cri_key, (cri->cri_klen + 7) / 8);+			} else {+				/* OCF doesn't enforce keys */+				crypto_blkcipher_set_flags(+						crypto_blkcipher_cast((*swd)->sw_tfm),+							CRYPTO_TFM_REQ_WEAK_KEY);+				error = crypto_blkcipher_setkey(+							crypto_blkcipher_cast((*swd)->sw_tfm),+								cri->cri_key, (cri->cri_klen + 7) / 8);+			}+			if (error) {+				printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,+						(*swd)->sw_tfm->crt_flags);+				swcr_freesession(NULL, i);+				return error;+			}+		} else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {+			dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,+					algo, mode);++			/* try async first */+			(*swd)->sw_tfm = swcr_no_ahash ? NULL :+					crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));+			if ((*swd)->sw_tfm) {+				dprintk("%s %s hash is async\n", __FUNCTION__, algo);+				(*swd)->sw_type |= SW_TYPE_ASYNC;+			} else {+				dprintk("%s %s hash is sync\n", __FUNCTION__, algo);+				(*swd)->sw_tfm = crypto_hash_tfm(+						crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));+			}++			if (!(*swd)->sw_tfm) {+				dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",+						algo, mode);+				swcr_freesession(NULL, i);+				return EINVAL;+			}++			(*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;+			(*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,+					SLAB_ATOMIC);+			if ((*swd)->u.hmac.sw_key == NULL) {+				swcr_freesession(NULL, i);+				dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+				return ENOBUFS;+			}+			memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);+			if (cri->cri_mlen) {+				(*swd)->u.hmac.sw_mlen = cri->cri_mlen;+			} else if ((*swd)->sw_type & SW_TYPE_ASYNC) {+				(*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(+						__crypto_ahash_cast((*swd)->sw_tfm));+			} else  {+				(*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(+						crypto_hash_cast((*swd)->sw_tfm));+			}+		} else if ((*swd)->sw_type & SW_TYPE_COMP) {+			(*swd)->sw_tfm = crypto_comp_tfm(+					crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));+			if (!(*swd)->sw_tfm) {+				dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",+						algo, mode);+				swcr_freesession(NULL, i);+				return EINVAL;+			}+			(*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);+			if ((*swd)->u.sw_comp_buf == NULL) {+				swcr_freesession(NULL, i);+				dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+				return ENOBUFS;+			}+		} else {+			printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);+			swcr_freesession(NULL, i);+			return EINVAL;+		}++		cri = cri->cri_next;+		swd = &((*swd)->sw_next);+	}+	return 0;+}++/*+ * Free a session.+ */+static int+swcr_freesession(device_t dev, u_int64_t tid)+{+	struct swcr_data *swd;+	u_int32_t sid = CRYPTO_SESID2LID(tid);++	dprintk("%s()\n", __FUNCTION__);+	if (sid > swcr_sesnum || swcr_sessions == NULL ||+			swcr_sessions[sid] == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return(EINVAL);+	}++	/* Silently accept and return */+	if (sid == 0)+		return(0);++	while ((swd = swcr_sessions[sid]) != NULL) {+		swcr_sessions[sid] = swd->sw_next;+		if (swd->sw_tfm) {+			switch (swd->sw_type & SW_TYPE_ALG_AMASK) {+#ifdef HAVE_AHASH+			case SW_TYPE_AHMAC:+			case SW_TYPE_AHASH:+				crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));+				break;+#endif+#ifdef HAVE_ABLKCIPHER+			case SW_TYPE_ABLKCIPHER:+				crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));+				break;+#endif+			case SW_TYPE_BLKCIPHER:+				crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));+				break;+			case SW_TYPE_HMAC:+			case SW_TYPE_HASH:+				crypto_free_hash(crypto_hash_cast(swd->sw_tfm));+				break;+			case SW_TYPE_COMP:+				crypto_free_comp(crypto_comp_cast(swd->sw_tfm));+			default:+				crypto_free_tfm(swd->sw_tfm);+				break;+			}+			swd->sw_tfm = NULL;+		}+		if (swd->sw_type & SW_TYPE_COMP) {+			if (swd->u.sw_comp_buf)+				kfree(swd->u.sw_comp_buf);+		} else {+			if (swd->u.hmac.sw_key)+				kfree(swd->u.hmac.sw_key);+		}+		kfree(swd);+	}+	return 0;+}++#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)+/* older kernels had no async interface */++static void swcr_process_callback(struct crypto_async_request *creq, int err)+{+	struct swcr_req *req = creq->data;++	dprintk("%s()\n", __FUNCTION__);+	if (err) {+		if (err == -EINPROGRESS)+			return;+		dprintk("%s() fail %d\n", __FUNCTION__, -err);+		req->crp->crp_etype = -err;+		goto done;+	}++	switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {+	case SW_TYPE_AHMAC:+	case SW_TYPE_AHASH:+		crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,+				req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);+		ahash_request_free(req->crypto_req);+		break;+	case SW_TYPE_ABLKCIPHER:+		ablkcipher_request_free(req->crypto_req);+		break;+	default:+		req->crp->crp_etype = EINVAL;+		goto done;+	}++	req->crd = req->crd->crd_next;+	if (req->crd) {+		swcr_process_req(req);+		return;+	}++done:+	dprintk("%s crypto_done %p\n", __FUNCTION__, req);+	crypto_done(req->crp);+	kmem_cache_free(swcr_req_cache, req);+}+#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */+++static void swcr_process_req(struct swcr_req *req)+{+	struct swcr_data *sw;+	struct cryptop *crp = req->crp;+	struct cryptodesc *crd = req->crd;+	struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;+	struct uio *uiop = (struct uio *) crp->crp_buf;+	int sg_num, sg_len, skip;++	dprintk("%s()\n", __FUNCTION__);++	/*+	 * Find the crypto context.+	 *+	 * XXX Note that the logic here prevents us from having+	 * XXX the same algorithm multiple times in a session+	 * XXX (or rather, we can but it won't give us the right+	 * XXX results). To do that, we'd need some way of differentiating+	 * XXX between the various instances of an algorithm (so we can+	 * XXX locate the correct crypto context).+	 */+	for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)+		;++	/* No such context ? */+	if (sw == NULL) {+		crp->crp_etype = EINVAL;+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		goto done;+	}++	req->sw = sw;+	skip = crd->crd_skip;++	/*+	 * setup the SG list skip from the start of the buffer+	 */+	memset(req->sg, 0, sizeof(req->sg));+	sg_init_table(req->sg, SCATTERLIST_MAX);+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		int i, len;++		sg_num = 0;+		sg_len = 0;++		if (skip < skb_headlen(skb)) {+			len = skb_headlen(skb) - skip;+			if (len + sg_len > crd->crd_len)+				len = crd->crd_len - sg_len;+			sg_set_page(&req->sg[sg_num],+				virt_to_page(skb->data + skip), len,+				offset_in_page(skb->data + skip));+			sg_len += len;+			sg_num++;+			skip = 0;+		} else+			skip -= skb_headlen(skb);++		for (i = 0; sg_len < crd->crd_len &&+					i < skb_shinfo(skb)->nr_frags &&+					sg_num < SCATTERLIST_MAX; i++) {+			if (skip < skb_shinfo(skb)->frags[i].size) {+				len = skb_shinfo(skb)->frags[i].size - skip;+				if (len + sg_len > crd->crd_len)+					len = crd->crd_len - sg_len;+				sg_set_page(&req->sg[sg_num],+					skb_shinfo(skb)->frags[i].page,+					len,+					skb_shinfo(skb)->frags[i].page_offset + skip);+				sg_len += len;+				sg_num++;+				skip = 0;+			} else+				skip -= skb_shinfo(skb)->frags[i].size;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		int len;++		sg_len = 0;+		for (sg_num = 0; sg_len < crd->crd_len &&+				sg_num < uiop->uio_iovcnt &&+				sg_num < SCATTERLIST_MAX; sg_num++) {+			if (skip <= uiop->uio_iov[sg_num].iov_len) {+				len = uiop->uio_iov[sg_num].iov_len - skip;+				if (len + sg_len > crd->crd_len)+					len = crd->crd_len - sg_len;+				sg_set_page(&req->sg[sg_num],+					virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),+					len,+					offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));+				sg_len += len;+				skip = 0;+			} else +				skip -= uiop->uio_iov[sg_num].iov_len;+		}+	} else {+		sg_len = (crp->crp_ilen - skip);+		if (sg_len > crd->crd_len)+			sg_len = crd->crd_len;+		sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),+			sg_len, offset_in_page(crp->crp_buf + skip));+		sg_num = 1;+	}++	switch (sw->sw_type & SW_TYPE_ALG_AMASK) {++#ifdef HAVE_AHASH+	case SW_TYPE_AHMAC:+	case SW_TYPE_AHASH:+		{+		int ret;++		/* check we have room for the result */+		if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {+			dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "+					"digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,+					crd->crd_inject, sw->u.hmac.sw_mlen);+			crp->crp_etype = EINVAL;+			goto done;+		}++		req->crypto_req =+				ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);+		if (!req->crypto_req) {+			crp->crp_etype = ENOMEM;+			dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);+			goto done;+		}++		ahash_request_set_callback(req->crypto_req,+				CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);++		memset(req->result, 0, sizeof(req->result));++		if (sw->sw_type & SW_TYPE_AHMAC)+			crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),+					sw->u.hmac.sw_key, sw->u.hmac.sw_klen);+		ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);+		ret = crypto_ahash_digest(req->crypto_req);+		switch (ret) {+		case -EINPROGRESS:+		case -EBUSY:+			return;+		default:+		case 0:+			dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);+			crp->crp_etype = ret;+			ahash_request_free(req->crypto_req);+			goto done;+		}+		} break;+#endif /* HAVE_AHASH */++#ifdef HAVE_ABLKCIPHER+	case SW_TYPE_ABLKCIPHER: {+		int ret;+		unsigned char *ivp = req->iv;+		int ivsize = +			crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));++		if (sg_len < crypto_ablkcipher_blocksize(+				__crypto_ablkcipher_cast(sw->sw_tfm))) {+			crp->crp_etype = EINVAL;+			dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,+					sg_len, crypto_ablkcipher_blocksize(+						__crypto_ablkcipher_cast(sw->sw_tfm)));+			goto done;+		}++		if (ivsize > sizeof(req->iv)) {+			crp->crp_etype = EINVAL;+			dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+			goto done;+		}++		req->crypto_req = ablkcipher_request_alloc(+				__crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);+		if (!req->crypto_req) {+			crp->crp_etype = ENOMEM;+			dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",+					__FILE__, __LINE__);+			goto done;+		}++		ablkcipher_request_set_callback(req->crypto_req,+				CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);++		if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {+			int i, error;++			if (debug) {+				dprintk("%s key:", __FUNCTION__);+				for (i = 0; i < (crd->crd_klen + 7) / 8; i++)+					dprintk("%s0x%x", (i % 8) ? " " : "\n    ",+							crd->crd_key[i] & 0xff);+				dprintk("\n");+			}+			/* OCF doesn't enforce keys */+			crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),+					CRYPTO_TFM_REQ_WEAK_KEY);+			error = crypto_ablkcipher_setkey(+						__crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,+						(crd->crd_klen + 7) / 8);+			if (error) {+				dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",+						error, sw->sw_tfm->crt_flags);+				crp->crp_etype = -error;+			}+		}++		if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */++			if (crd->crd_flags & CRD_F_IV_EXPLICIT)+				ivp = crd->crd_iv;+			else+				get_random_bytes(ivp, ivsize);+			/*+			 * do we have to copy the IV back to the buffer ?+			 */+			if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {+				crypto_copyback(crp->crp_flags, crp->crp_buf,+						crd->crd_inject, ivsize, (caddr_t)ivp);+			}+			ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,+					sg_len, ivp);+			ret = crypto_ablkcipher_encrypt(req->crypto_req);++		} else { /*decrypt */++			if (crd->crd_flags & CRD_F_IV_EXPLICIT)+				ivp = crd->crd_iv;+			else+				crypto_copydata(crp->crp_flags, crp->crp_buf,+						crd->crd_inject, ivsize, (caddr_t)ivp);+			ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,+					sg_len, ivp);+			ret = crypto_ablkcipher_decrypt(req->crypto_req);+		}++		switch (ret) {+		case -EINPROGRESS:+		case -EBUSY:+			return;+		default:+		case 0:+			dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);+			crp->crp_etype = ret;+			goto done;+		}+		} break;+#endif /* HAVE_ABLKCIPHER */++	case SW_TYPE_BLKCIPHER: {+		unsigned char iv[EALG_MAX_BLOCK_LEN];+		unsigned char *ivp = iv;+		struct blkcipher_desc desc;+		int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));++		if (sg_len < crypto_blkcipher_blocksize(+				crypto_blkcipher_cast(sw->sw_tfm))) {+			crp->crp_etype = EINVAL;+			dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,+					sg_len, crypto_blkcipher_blocksize(+						crypto_blkcipher_cast(sw->sw_tfm)));+			goto done;+		}++		if (ivsize > sizeof(iv)) {+			crp->crp_etype = EINVAL;+			dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+			goto done;+		}++		if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {+			int i, error;++			if (debug) {+				dprintk("%s key:", __FUNCTION__);+				for (i = 0; i < (crd->crd_klen + 7) / 8; i++)+					dprintk("%s0x%x", (i % 8) ? " " : "\n    ",+							crd->crd_key[i] & 0xff);+				dprintk("\n");+			}+			/* OCF doesn't enforce keys */+			crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),+					CRYPTO_TFM_REQ_WEAK_KEY);+			error = crypto_blkcipher_setkey(+						crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,+						(crd->crd_klen + 7) / 8);+			if (error) {+				dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",+						error, sw->sw_tfm->crt_flags);+				crp->crp_etype = -error;+			}+		}++		memset(&desc, 0, sizeof(desc));+		desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);++		if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */++			if (crd->crd_flags & CRD_F_IV_EXPLICIT) {+				ivp = crd->crd_iv;+			} else {+				get_random_bytes(ivp, ivsize);+			}+			/*+			 * do we have to copy the IV back to the buffer ?+			 */+			if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {+				crypto_copyback(crp->crp_flags, crp->crp_buf,+						crd->crd_inject, ivsize, (caddr_t)ivp);+			}+			desc.info = ivp;+			crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);++		} else { /*decrypt */++			if (crd->crd_flags & CRD_F_IV_EXPLICIT) {+				ivp = crd->crd_iv;+			} else {+				crypto_copydata(crp->crp_flags, crp->crp_buf,+						crd->crd_inject, ivsize, (caddr_t)ivp);+			}+			desc.info = ivp;+			crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);+		}+		} break;++	case SW_TYPE_HMAC:+	case SW_TYPE_HASH:+		{+		char result[HASH_MAX_LEN];+		struct hash_desc desc;++		/* check we have room for the result */+		if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {+			dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "+					"digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,+					crd->crd_inject, sw->u.hmac.sw_mlen);+			crp->crp_etype = EINVAL;+			goto done;+		}++		memset(&desc, 0, sizeof(desc));+		desc.tfm = crypto_hash_cast(sw->sw_tfm);++		memset(result, 0, sizeof(result));++		if (sw->sw_type & SW_TYPE_HMAC) {+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+			crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,+					req->sg, sg_num, result);+#else+			crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,+					sw->u.hmac.sw_klen);+			crypto_hash_digest(&desc, req->sg, sg_len, result);+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */+			+		} else { /* SW_TYPE_HASH */+			crypto_hash_digest(&desc, req->sg, sg_len, result);+		}++		crypto_copyback(crp->crp_flags, crp->crp_buf,+				crd->crd_inject, sw->u.hmac.sw_mlen, result);+		}+		break;++	case SW_TYPE_COMP: {+		void *ibuf = NULL;+		void *obuf = sw->u.sw_comp_buf;+		int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;+		int ret = 0;++		/*+		 * we need to use an additional copy if there is more than one+		 * input chunk since the kernel comp routines do not handle+		 * SG yet.  Otherwise we just use the input buffer as is.+		 * Rather than allocate another buffer we just split the tmp+		 * buffer we already have.+		 * Perhaps we should just use zlib directly ?+		 */+		if (sg_num > 1) {+			int blk;++			ibuf = obuf;+			for (blk = 0; blk < sg_num; blk++) {+				memcpy(obuf, sg_virt(&req->sg[blk]),+						req->sg[blk].length);+				obuf += req->sg[blk].length;+			}+			olen -= sg_len;+		} else+			ibuf = sg_virt(&req->sg[0]);++		if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */+			ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),+					ibuf, ilen, obuf, &olen);+			if (!ret && olen > crd->crd_len) {+				dprintk("cryptosoft: ERANGE compress %d into %d\n",+						crd->crd_len, olen);+				if (swcr_fail_if_compression_grows)+					ret = ERANGE;+			}+		} else { /* decompress */+			ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),+					ibuf, ilen, obuf, &olen);+			if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {+				dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "+						"space for %d,at offset %d\n",+						crd->crd_len, olen, crp->crp_olen, crd->crd_inject);+				ret = ETOOSMALL;+			}+		}+		if (ret)+			dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);++		/*+		 * on success copy result back,+		 * linux crpyto API returns -errno,  we need to fix that+		 */+		crp->crp_etype = ret < 0 ? -ret : ret;+		if (ret == 0) {+			/* copy back the result and return it's size */+			crypto_copyback(crp->crp_flags, crp->crp_buf,+					crd->crd_inject, olen, obuf);+			crp->crp_olen = olen;+		}+++		} break;++	default:+		/* Unknown/unsupported algorithm */+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	}++done:+	crypto_done(crp);+	kmem_cache_free(swcr_req_cache, req);+}+++/*+ * Process a crypto request.+ */+static int+swcr_process(device_t dev, struct cryptop *crp, int hint)+{+	struct swcr_req *req = NULL;+	u_int32_t lid;++	dprintk("%s()\n", __FUNCTION__);+	/* Sanity check */+	if (crp == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	crp->crp_etype = 0;++	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	}++	lid = crp->crp_sid & 0xffffffff;+	if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||+			swcr_sessions[lid] == NULL) {+		crp->crp_etype = ENOENT;+		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);+		goto done;+	}++	/*+	 * do some error checking outside of the loop for SKB and IOV processing+	 * this leaves us with valid skb or uiop pointers for later+	 */+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;+		if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {+			printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,+					skb_shinfo(skb)->nr_frags);+			goto done;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		struct uio *uiop = (struct uio *) crp->crp_buf;+		if (uiop->uio_iovcnt > SCATTERLIST_MAX) {+			printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,+					uiop->uio_iovcnt);+			goto done;+		}+	}++	/*+	 * setup a new request ready for queuing+	 */+	req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);+	if (req == NULL) {+		dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);+		crp->crp_etype = ENOMEM;+		goto done;+	}+	memset(req, 0, sizeof(*req));++	req->sw_head = swcr_sessions[lid];+	req->crp = crp;+	req->crd = crp->crp_desc;++	swcr_process_req(req);+	return 0;++done:+	crypto_done(crp);+	if (req)+		kmem_cache_free(swcr_req_cache, req);+	return 0;+}+++static int+cryptosoft_init(void)+{+	int i, sw_type, mode;+	char *algo;++	dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);++	swcr_req_cache = kmem_cache_create("cryptosoft_req",+				sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)+				, NULL+#endif+				);+	if (!swcr_req_cache) {+		printk("cryptosoft: failed to create request cache\n");+		return -ENOENT;+	}++	softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);++	swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),+			CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);+	if (swcr_id < 0) {+		printk("cryptosoft: Software crypto device cannot initialize!");+		return -ENODEV;+	}++#define	REGISTER(alg) \+		crypto_register(swcr_id, alg, 0,0)++	for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {+		int found;+		+		algo = crypto_details[i].alg_name;+		if (!algo || !*algo) {+			dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);+			continue;+		}++		mode = crypto_details[i].mode;+		sw_type = crypto_details[i].sw_type;++		found = 0;+		switch (sw_type & SW_TYPE_ALG_MASK) {+		case SW_TYPE_CIPHER:+			found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);+			break;+		case SW_TYPE_HMAC:+			found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);+			break;+		case SW_TYPE_HASH:+			found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);+			break;+		case SW_TYPE_COMP:+			found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);+			break;+		case SW_TYPE_BLKCIPHER:+			found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);+			if (!found && !swcr_no_ablk)+				found = crypto_has_ablkcipher(algo, 0, 0);+			break;+		}+		if (found) {+			REGISTER(i);+		} else {+			dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",+					__FUNCTION__, sw_type, i, algo);+		}+	}+	return 0;+}++static void+cryptosoft_exit(void)+{+	dprintk("%s()\n", __FUNCTION__);+	crypto_unregister_all(swcr_id);+	swcr_id = -1;+	kmem_cache_destroy(swcr_req_cache);+}++late_initcall(cryptosoft_init);+module_exit(cryptosoft_exit);++MODULE_LICENSE("Dual BSD/GPL");+MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");+MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.36/crypto/ocf/ep80579/icp_asym.c--- linux-2.6.36.orig/crypto/ocf/ep80579/icp_asym.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ep80579/icp_asym.c	2010-11-09 20:28:04.572486503 +0100@@ -0,0 +1,1334 @@+/***************************************************************************+ *+ * This file is provided under a dual BSD/GPLv2 license.  When using or + *   redistributing this file, you may do so under either license.+ * + *   GPL LICENSE SUMMARY+ * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of version 2 of the GNU General Public License as+ *   published by the Free Software Foundation.+ * + *   This program is distributed in the hope that it will be useful, but + *   WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *   General Public License for more details.+ * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.+ *   The full GNU General Public License is included in this distribution + *   in the file called LICENSE.GPL.+ * + *   Contact Information:+ *   Intel Corporation+ * + *   BSD LICENSE + * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ *   All rights reserved.+ * + *   Redistribution and use in source and binary forms, with or without + *   modification, are permitted provided that the following conditions + *   are met:+ * + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer.+ *     * Redistributions in binary form must reproduce the above copyright + *       notice, this list of conditions and the following disclaimer in + *       the documentation and/or other materials provided with the + *       distribution.+ *     * Neither the name of Intel Corporation nor the names of its + *       contributors may be used to endorse or promote products derived + *       from this software without specific prior written permission.+ * + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ * + * + *  version: Security.L.1.0.2-229+ *+ ***************************************************************************/++#include "icp_ocf.h"++/*The following define values (containing the word 'INDEX') are used to find+the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).+These values were found through analysis of the OCF OpenSSL patch. If the+calling program uses different input buffer positions, these defines will have+to be changed.*/++/*DIFFIE HELLMAN buffer index values*/+#define ICP_DH_KRP_PARAM_PRIME_INDEX                            (0)+#define ICP_DH_KRP_PARAM_BASE_INDEX                             (1)+#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX                    (2)+#define ICP_DH_KRP_PARAM_RESULT_INDEX                           (3)++/*MOD EXP buffer index values*/+#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX                        (0)+#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX                    (1)+#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX                     (2)+#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX                      (3)++/*MOD EXP CRT buffer index values*/+#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX                 (0)+#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX                 (1)+#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX                       (2)+#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX             (3)+#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX             (4)+#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX              (5)+#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX                  (6)++/*DSA sign buffer index values*/+#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX                       (0)+#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX                    (1)+#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX                    (2)+#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX                          (3)+#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX                          (4)+#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX                   (5)+#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX                   (6)++/*DSA verify buffer index values*/+#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX                     (0)+#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX                  (1)+#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX                  (2)+#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX                        (3)+#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX                   (4)+#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX                    (5)+#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX                    (6)++/*DSA sign prime Q vs random number K size check values*/+#define DONT_RUN_LESS_THAN_CHECK                                (0)+#define FAIL_A_IS_GREATER_THAN_B                                (1)+#define FAIL_A_IS_EQUAL_TO_B                                    (1)+#define SUCCESS_A_IS_LESS_THAN_B                                (0)+#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS              (500)++/* We need to set a cryptokp success value just in case it is set or allocated+   and not set to zero outside of this module */+#define CRYPTO_OP_SUCCESS                                       (0)++/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/+static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);++/*Function to compute a Modular Exponentiation (Mod Exp)*/+static int icp_ocfDrvModExp(struct cryptkop *krp);++/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/+static int icp_ocfDrvModExpCRT(struct cryptkop *krp);++/*Helper function to compute whether the first big number argument is less than+ the second big number argument */+static int+icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);++/*Function to sign an input with DSA R and S keys*/+static int icp_ocfDrvDsaSign(struct cryptkop *krp);++/*Function to Verify a DSA buffer signature*/+static int icp_ocfDrvDsaVerify(struct cryptkop *krp);++/*Callback function for DH operation*/+static void+icp_ocfDrvDhP1CallBack(void *callbackTag,+		       CpaStatus status,+		       void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);++/*Callback function for ME operation*/+static void+icp_ocfDrvModExpCallBack(void *callbackTag,+			 CpaStatus status,+			 void *pOpData, CpaFlatBuffer * pResult);++/*Callback function for ME CRT operation*/+static void+icp_ocfDrvModExpCRTCallBack(void *callbackTag,+			    CpaStatus status,+			    void *pOpData, CpaFlatBuffer * pOutputData);++/*Callback function for DSA sign operation*/+static void+icp_ocfDrvDsaRSSignCallBack(void *callbackTag,+			    CpaStatus status,+			    void *pOpData,+			    CpaBoolean protocolStatus,+			    CpaFlatBuffer * pR, CpaFlatBuffer * pS);++/*Callback function for DSA Verify operation*/+static void+icp_ocfDrvDsaVerifyCallBack(void *callbackTag,+			    CpaStatus status,+			    void *pOpData, CpaBoolean verifyStatus);++/* Name        : icp_ocfDrvPkeProcess+ *+ * Description : This function will choose which PKE process to follow+ * based on the input arguments+ */+int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;++	if (NULL == krp) {+		DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",+			__FUNCTION__, krp);+		return EINVAL;+	}++	if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {+		krp->krp_status = ECANCELED;+		return ECANCELED;+	}++	switch (krp->krp_op) {+	case CRK_DH_COMPUTE_KEY:+		DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);+		lacStatus = icp_ocfDrvDHComputeKey(krp);+		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "+				"(%d).\n", __FUNCTION__, lacStatus);+			krp->krp_status = ECANCELED;+			return ECANCELED;+		}++		break;++	case CRK_MOD_EXP:+		DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);+		lacStatus = icp_ocfDrvModExp(krp);+		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",+				__FUNCTION__, lacStatus);+			krp->krp_status = ECANCELED;+			return ECANCELED;+		}++		break;++	case CRK_MOD_EXP_CRT:+		DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);+		lacStatus = icp_ocfDrvModExpCRT(krp);+		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): icp_ocfDrvModExpCRT "+				"failed (%d).\n", __FUNCTION__, lacStatus);+			krp->krp_status = ECANCELED;+			return ECANCELED;+		}++		break;++	case CRK_DSA_SIGN:+		DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);+		lacStatus = icp_ocfDrvDsaSign(krp);+		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): icp_ocfDrvDsaSign "+				"failed (%d).\n", __FUNCTION__, lacStatus);+			krp->krp_status = ECANCELED;+			return ECANCELED;+		}++		break;++	case CRK_DSA_VERIFY:+		DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);+		lacStatus = icp_ocfDrvDsaVerify(krp);+		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): icp_ocfDrvDsaVerify "+				"failed (%d).\n", __FUNCTION__, lacStatus);+			krp->krp_status = ECANCELED;+			return ECANCELED;+		}++		break;++	default:+		EPRINTK("%s(): Asymettric function not "+			"supported (%d).\n", __FUNCTION__, krp->krp_op);+		krp->krp_status = EOPNOTSUPP;+		return EOPNOTSUPP;+	}++	return ICP_OCF_DRV_STATUS_SUCCESS;+}++/* Name        : icp_ocfDrvSwapBytes+ *+ * Description : This function is used to swap the byte order of a buffer.+ * It has been seen that in general we are passed little endian byte order+ * buffers, but LAC only accepts big endian byte order buffers.+ */+static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)+{++	int i;+	u_int8_t *end_ptr;+	u_int8_t hold_val;++	end_ptr = num + (buff_len_bytes - 1);+	buff_len_bytes = buff_len_bytes >> 1;+	for (i = 0; i < buff_len_bytes; i++) {+		hold_val = *num;+		*num = *end_ptr;+		num++;+		*end_ptr = hold_val;+		end_ptr--;+	}+}++/* Name        : icp_ocfDrvDHComputeKey+ *+ * Description : This function will map Diffie Hellman calls from OCF+ * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and+ * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases+ * break down to a modular exponentiation.+ */+static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	void *callbackTag = NULL;+	CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;+	CpaFlatBuffer *pLocalOctetStringPV = NULL;+	uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;++	/* Input checks - check prime is a multiple of 8 bits to allow for+	   allocation later */+	dh_prime_len_bits =+	    (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);++	/* LAC can reject prime lengths based on prime key sizes, we just+	   need to make sure we can allocate space for the base and+	   exponent buffers correctly */+	if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {+		APRINTK("%s(): Warning Prime number buffer size is not a "+			"multiple of 8 bits\n", __FUNCTION__);+	}++	/* Result storage space should be the same size as the prime as this+	   value can take up the same amount of storage space */+	if (dh_prime_len_bits !=+	    krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {+		DPRINTK("%s(): Return Buffer must be the same size "+			"as the Prime buffer\n", __FUNCTION__);+		krp->krp_status = EINVAL;+		return EINVAL;+	}+	/* Switch to size in bytes */+	BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);++	callbackTag = krp;++/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting+called in interrupt context*/+	pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);+	if (NULL == pPhase1OpData) {+		APRINTK("%s():Failed to get memory for key gen data\n",+			__FUNCTION__);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	pLocalOctetStringPV =+	    icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);+	if (NULL == pLocalOctetStringPV) {+		APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",+			__FUNCTION__);+		ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	/* Link parameters */+	pPhase1OpData->primeP.pData =+	    krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;++	pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;++	icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);++	pPhase1OpData->baseG.pData =+	    krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;++	BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,+		      krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);++	icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,+			    pPhase1OpData->baseG.dataLenInBytes);++	pPhase1OpData->privateValueX.pData =+	    krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;++	BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,+		      krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,+			    pPhase1OpData->privateValueX.dataLenInBytes);++	/* Output parameters */+	pLocalOctetStringPV->pData =+	    krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;++	BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,+		      krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);++	lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,+					icp_ocfDrvDhP1CallBack,+					callbackTag, pPhase1OpData,+					pLocalOctetStringPV);++	if (CPA_STATUS_SUCCESS != lacStatus) {+		EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",+			__FUNCTION__, lacStatus);+		icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);+		ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);+	}++	return lacStatus;+}++/* Name        : icp_ocfDrvModExp+ *+ * Description : This function will map ordinary Modular Exponentiation calls+ * from OCF to the LAC API.+ *+ */+static int icp_ocfDrvModExp(struct cryptkop *krp)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	void *callbackTag = NULL;+	CpaCyLnModExpOpData *pModExpOpData = NULL;+	CpaFlatBuffer *pResult = NULL;++	if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %+	     NUM_BITS_IN_BYTE) != 0) {+		DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "+			"multiple of 8 bits\n", __FUNCTION__,+			krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].+			crp_nbits);+	}++	/* Result storage space should be the same size as the prime as this+	   value can take up the same amount of storage space */+	if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >+	    krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {+		APRINTK("%s(): Return Buffer size must be the same or"+			" greater than the Modulus buffer\n", __FUNCTION__);+		krp->krp_status = EINVAL;+		return EINVAL;+	}++	callbackTag = krp;++	pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);+	if (NULL == pModExpOpData) {+		APRINTK("%s():Failed to get memory for key gen data\n",+			__FUNCTION__);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);+	if (NULL == pResult) {+		APRINTK("%s():Failed to get memory for ModExp result\n",+			__FUNCTION__);+		ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	/* Link parameters */+	pModExpOpData->modulus.pData =+	    krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;+	BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,+			    pModExpOpData->modulus.dataLenInBytes);++	DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->+		krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);+	pModExpOpData->base.pData =+	    krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;+	BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(pModExpOpData->base.pData,+			    pModExpOpData->base.dataLenInBytes);++	pModExpOpData->exponent.pData =+	    krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;+	BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,+			    pModExpOpData->exponent.dataLenInBytes);+	/* Output parameters */+	pResult->pData =+	    krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,+	    BITS_TO_BYTES(pResult->dataLenInBytes,+			  krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].+			  crp_nbits);++	lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,+				  icp_ocfDrvModExpCallBack,+				  callbackTag, pModExpOpData, pResult);++	if (CPA_STATUS_SUCCESS != lacStatus) {+		EPRINTK("%s(): Mod Exp Operation failed (%d).\n",+			__FUNCTION__, lacStatus);+		krp->krp_status = ECANCELED;+		icp_ocfDrvFreeFlatBuffer(pResult);+		ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);+	}++	return lacStatus;+}++/* Name        : icp_ocfDrvModExpCRT+ *+ * Description : This function will map ordinary Modular Exponentiation Chinese+ * Remainder Theorem implementaion calls from OCF to the LAC API.+ *+ * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2+ * decrypt operation. Therefore P and Q input values must always be prime+ * numbers. Although basic primality checks are done in LAC, it is up to the+ * user to do any correct prime number checking before passing the inputs.+ */+static int icp_ocfDrvModExpCRT(struct cryptkop *krp)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;+	void *callbackTag = NULL;+	CpaFlatBuffer *pOutputData = NULL;++	/*Parameter input checks are all done by LAC, no need to repeat+	   them here. */+	callbackTag = krp;++	rsaDecryptOpData =+	    icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);+	if (NULL == rsaDecryptOpData) {+		APRINTK("%s():Failed to get memory"+			" for MOD EXP CRT Op data struct\n", __FUNCTION__);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	rsaDecryptOpData->pRecipientPrivateKey+	    = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);+	if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {+		APRINTK("%s():Failed to get memory for MOD EXP CRT"+			" private key values struct\n", __FUNCTION__);+		ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	rsaDecryptOpData->pRecipientPrivateKey->+	    version = CPA_CY_RSA_VERSION_TWO_PRIME;+	rsaDecryptOpData->pRecipientPrivateKey->+	    privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;++	pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);+	if (NULL == pOutputData) {+		APRINTK("%s():Failed to get memory"+			" for MOD EXP CRT output data\n", __FUNCTION__);+		ICP_CACHE_FREE(drvRSAPrivateKey_zone,+			       rsaDecryptOpData->pRecipientPrivateKey);+		ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	rsaDecryptOpData->pRecipientPrivateKey->+	    version = CPA_CY_RSA_VERSION_TWO_PRIME;+	rsaDecryptOpData->pRecipientPrivateKey->+	    privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;++	/* Link parameters */+	rsaDecryptOpData->inputData.pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;+	BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,+			    rsaDecryptOpData->inputData.dataLenInBytes);++	rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;+	BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.+		      prime1P.dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.prime1P.pData,+			    rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.prime1P.dataLenInBytes);++	rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;+	BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.+		      prime2Q.dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.prime2Q.pData,+			    rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.prime2Q.dataLenInBytes);++	rsaDecryptOpData->pRecipientPrivateKey->+	    privateKeyRep2.exponent1Dp.pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;+	BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.+		      exponent1Dp.dataLenInBytes,+		      krp->+		      krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.exponent1Dp.pData,+			    rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.exponent1Dp.dataLenInBytes);++	rsaDecryptOpData->pRecipientPrivateKey->+	    privateKeyRep2.exponent2Dq.pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;+	BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->+		      privateKeyRep2.exponent2Dq.dataLenInBytes,+		      krp->+		      krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.exponent2Dq.pData,+			    rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.exponent2Dq.dataLenInBytes);++	rsaDecryptOpData->pRecipientPrivateKey->+	    privateKeyRep2.coefficientQInv.pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;+	BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->+		      privateKeyRep2.coefficientQInv.dataLenInBytes,+		      krp->+		      krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.coefficientQInv.pData,+			    rsaDecryptOpData->pRecipientPrivateKey->+			    privateKeyRep2.coefficientQInv.dataLenInBytes);++	/* Output Parameter */+	pOutputData->pData =+	    krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;+	BITS_TO_BYTES(pOutputData->dataLenInBytes,+		      krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].+		      crp_nbits);++	lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,+				    icp_ocfDrvModExpCRTCallBack,+				    callbackTag, rsaDecryptOpData, pOutputData);++	if (CPA_STATUS_SUCCESS != lacStatus) {+		EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",+			__FUNCTION__, lacStatus);+		krp->krp_status = ECANCELED;+		icp_ocfDrvFreeFlatBuffer(pOutputData);+		ICP_CACHE_FREE(drvRSAPrivateKey_zone,+			       rsaDecryptOpData->pRecipientPrivateKey);+		ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);+	}++	return lacStatus;+}++/* Name        : icp_ocfDrvCheckALessThanB+ *+ * Description : This function will check whether the first argument is less+ * than the second. It is used to check whether the DSA RS sign Random K+ * value is less than the Prime Q value (as defined in the specification)+ *+ */+static int+icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)+{++	uint8_t *MSB_K = pK->pData;+	uint8_t *MSB_Q = pQ->pData;+	uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;++	if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {+		return FAIL_A_IS_GREATER_THAN_B;+	}++/*Check MSBs+if A == B, check next MSB+if A > B, return A_IS_GREATER_THAN_B+if A < B, return A_IS_LESS_THAN_B (success)+*/+	while (*MSB_K == *MSB_Q) {+		MSB_K++;+		MSB_Q++;++		buffer_lengths_in_bytes--;+		if (0 == buffer_lengths_in_bytes) {+			DPRINTK("%s() Buffers have equal value!!\n",+				__FUNCTION__);+			return FAIL_A_IS_EQUAL_TO_B;+		}++	}++	if (*MSB_K < *MSB_Q) {+		return SUCCESS_A_IS_LESS_THAN_B;+	} else {+		return FAIL_A_IS_GREATER_THAN_B;+	}++}++/* Name        : icp_ocfDrvDsaSign+ *+ * Description : This function will map DSA RS Sign from OCF to the LAC API.+ *+ * NOTE: From looking at OCF patch to OpenSSL and even the number of input+ * parameters, OCF expects us to generate the random seed value. This value+ * is generated and passed to LAC, however the number is discared in the+ * callback and not returned to the user.+ */+static int icp_ocfDrvDsaSign(struct cryptkop *krp)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;+	void *callbackTag = NULL;+	CpaCyRandGenOpData randGenOpData;+	int primeQSizeInBytes = 0;+	int doCheck = 0;+	CpaFlatBuffer randData;+	CpaBoolean protocolStatus = CPA_FALSE;+	CpaFlatBuffer *pR = NULL;+	CpaFlatBuffer *pS = NULL;++	callbackTag = krp;++	BITS_TO_BYTES(primeQSizeInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].+		      crp_nbits);++	if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {+		APRINTK("%s(): DSA PRIME Q size not equal to the "+			"FIPS defined 20bytes, = %d\n",+			__FUNCTION__, primeQSizeInBytes);+		krp->krp_status = EDOM;+		return EDOM;+	}++	dsaRsSignOpData =+	    icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);+	if (NULL == dsaRsSignOpData) {+		APRINTK("%s():Failed to get memory"+			" for DSA RS Sign Op data struct\n", __FUNCTION__);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	dsaRsSignOpData->K.pData =+	    icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);++	if (NULL == dsaRsSignOpData->K.pData) {+		APRINTK("%s():Failed to get memory"+			" for DSA RS Sign Op Random value\n", __FUNCTION__);+		ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);+	if (NULL == pR) {+		APRINTK("%s():Failed to get memory"+			" for DSA signature R\n", __FUNCTION__);+		ICP_CACHE_FREE(drvDSARSSignKValue_zone,+			       dsaRsSignOpData->K.pData);+		ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);+	if (NULL == pS) {+		APRINTK("%s():Failed to get memory"+			" for DSA signature S\n", __FUNCTION__);+		icp_ocfDrvFreeFlatBuffer(pR);+		ICP_CACHE_FREE(drvDSARSSignKValue_zone,+			       dsaRsSignOpData->K.pData);+		ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	/*link prime number parameter for ease of processing */+	dsaRsSignOpData->P.pData =+	    krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;+	BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,+			    dsaRsSignOpData->P.dataLenInBytes);++	dsaRsSignOpData->Q.pData =+	    krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;+	BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].+		      crp_nbits);++	icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,+			    dsaRsSignOpData->Q.dataLenInBytes);++	/*generate random number with equal buffer size to Prime value Q,+	   but value less than Q */+	dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;++	randGenOpData.generateBits = CPA_TRUE;+	randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;++	icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,+					dsaRsSignOpData->K.dataLenInBytes,+					&randData);++	doCheck = 0;+	while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),+					 &(dsaRsSignOpData->Q), &doCheck)) {++		if (CPA_STATUS_SUCCESS+		    != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,+				    NULL, NULL, &randGenOpData, &randData)) {+			APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"+				"value\n", __FUNCTION__);+			icp_ocfDrvFreeFlatBuffer(pS);+			icp_ocfDrvFreeFlatBuffer(pR);+			ICP_CACHE_FREE(drvDSARSSignKValue_zone,+				       dsaRsSignOpData->K.pData);+			ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);+			krp->krp_status = EAGAIN;+			return EAGAIN;+		}++		doCheck++;+		if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {+			APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "+				"value less than Q value\n", __FUNCTION__);+			icp_ocfDrvFreeFlatBuffer(pS);+			icp_ocfDrvFreeFlatBuffer(pR);+			ICP_CACHE_FREE(drvDSARSSignKValue_zone,+				       dsaRsSignOpData->K.pData);+			ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);+			krp->krp_status = EAGAIN;+			return EAGAIN;+		}++	}+	/*Rand Data - no need to swap bytes for pK */++	/* Link parameters */+	dsaRsSignOpData->G.pData =+	    krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;+	BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);++	icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,+			    dsaRsSignOpData->G.dataLenInBytes);++	dsaRsSignOpData->X.pData =+	    krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;+	BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);+	icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,+			    dsaRsSignOpData->X.dataLenInBytes);++	/*OpenSSL dgst parameter is left in big endian byte order, +	   therefore no byte swap is required */+	dsaRsSignOpData->M.pData =+	    krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;+	BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].+		      crp_nbits);++	/* Output Parameters */+	pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;+	BITS_TO_BYTES(pS->dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].+		      crp_nbits);++	pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;+	BITS_TO_BYTES(pR->dataLenInBytes,+		      krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].+		      crp_nbits);++	lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,+				   icp_ocfDrvDsaRSSignCallBack,+				   callbackTag, dsaRsSignOpData,+				   &protocolStatus, pR, pS);++	if (CPA_STATUS_SUCCESS != lacStatus) {+		EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",+			__FUNCTION__, lacStatus);+		krp->krp_status = ECANCELED;+		icp_ocfDrvFreeFlatBuffer(pS);+		icp_ocfDrvFreeFlatBuffer(pR);+		ICP_CACHE_FREE(drvDSARSSignKValue_zone,+			       dsaRsSignOpData->K.pData);+		ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);+	}++	return lacStatus;+}++/* Name        : icp_ocfDrvDsaVerify+ *+ * Description : This function will map DSA RS Verify from OCF to the LAC API.+ *+ */+static int icp_ocfDrvDsaVerify(struct cryptkop *krp)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;+	void *callbackTag = NULL;+	CpaBoolean verifyStatus = CPA_FALSE;++	callbackTag = krp;++	dsaVerifyOpData =+	    icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);+	if (NULL == dsaVerifyOpData) {+		APRINTK("%s():Failed to get memory"+			" for DSA Verify Op data struct\n", __FUNCTION__);+		krp->krp_status = ENOMEM;+		return ENOMEM;+	}++	/* Link parameters */+	dsaVerifyOpData->P.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,+			    dsaVerifyOpData->P.dataLenInBytes);++	dsaVerifyOpData->Q.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,+			    dsaVerifyOpData->Q.dataLenInBytes);++	dsaVerifyOpData->G.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,+			    dsaVerifyOpData->G.dataLenInBytes);++	dsaVerifyOpData->Y.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,+			    dsaVerifyOpData->Y.dataLenInBytes);++	/*OpenSSL dgst parameter is left in big endian byte order, +	   therefore no byte swap is required */+	dsaVerifyOpData->M.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].+		      crp_nbits);++	dsaVerifyOpData->R.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,+			    dsaVerifyOpData->R.dataLenInBytes);++	dsaVerifyOpData->S.pData =+	    krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;+	BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,+		      krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].+		      crp_nbits);+	icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,+			    dsaVerifyOpData->S.dataLenInBytes);++	lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,+				   icp_ocfDrvDsaVerifyCallBack,+				   callbackTag, dsaVerifyOpData, &verifyStatus);++	if (CPA_STATUS_SUCCESS != lacStatus) {+		EPRINTK("%s(): DSA Verify Operation failed (%d).\n",+			__FUNCTION__, lacStatus);+		ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);+		krp->krp_status = ECANCELED;+	}++	return lacStatus;+}++/* Name        : icp_ocfDrvDhP1Callback+ *+ * Description : When this function returns it signifies that the LAC+ * component has completed the DH operation.+ */+static void+icp_ocfDrvDhP1CallBack(void *callbackTag,+		       CpaStatus status,+		       void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)+{+	struct cryptkop *krp = NULL;+	CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;++	if (NULL == callbackTag) {+		DPRINTK("%s(): Invalid input parameters - "+			"callbackTag data is NULL\n", __FUNCTION__);+		return;+	}+	krp = (struct cryptkop *)callbackTag;++	if (NULL == pOpData) {+		DPRINTK("%s(): Invalid input parameters - "+			"Operation Data is NULL\n", __FUNCTION__);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}+	pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;++	if (NULL == pLocalOctetStringPV) {+		DPRINTK("%s(): Invalid input parameters - "+			"pLocalOctetStringPV Data is NULL\n", __FUNCTION__);+		memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));+		ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}++	if (CPA_STATUS_SUCCESS == status) {+		krp->krp_status = CRYPTO_OP_SUCCESS;+	} else {+		APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "+			"Operation Status = %d\n", __FUNCTION__, status);+		krp->krp_status = ECANCELED;+	}++	icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,+			    pLocalOctetStringPV->dataLenInBytes);++	icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);+	memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));+	ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);++	crypto_kdone(krp);++	return;+}++/* Name        : icp_ocfDrvModExpCallBack+ *+ * Description : When this function returns it signifies that the LAC+ * component has completed the Mod Exp operation.+ */+static void+icp_ocfDrvModExpCallBack(void *callbackTag,+			 CpaStatus status,+			 void *pOpdata, CpaFlatBuffer * pResult)+{+	struct cryptkop *krp = NULL;+	CpaCyLnModExpOpData *pLnModExpOpData = NULL;++	if (NULL == callbackTag) {+		DPRINTK("%s(): Invalid input parameters - "+			"callbackTag data is NULL\n", __FUNCTION__);+		return;+	}+	krp = (struct cryptkop *)callbackTag;++	if (NULL == pOpdata) {+		DPRINTK("%s(): Invalid Mod Exp input parameters - "+			"Operation Data is NULL\n", __FUNCTION__);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}+	pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;++	if (NULL == pResult) {+		DPRINTK("%s(): Invalid input parameters - "+			"pResult data is NULL\n", __FUNCTION__);+		krp->krp_status = ECANCELED;+		memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));+		ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);+		crypto_kdone(krp);+		return;+	}++	if (CPA_STATUS_SUCCESS == status) {+		krp->krp_status = CRYPTO_OP_SUCCESS;+	} else {+		APRINTK("%s(): LAC Mod Exp Operation failed - "+			"Operation Status = %d\n", __FUNCTION__, status);+		krp->krp_status = ECANCELED;+	}++	icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);++	/*switch base size value back to original */+	if (pLnModExpOpData->base.pData ==+	    (uint8_t *) & (krp->+			   krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].+			   crp_nbits)) {+		*((uint32_t *) pLnModExpOpData->base.pData) =+		    ntohl(*((uint32_t *) pLnModExpOpData->base.pData));+	}+	icp_ocfDrvFreeFlatBuffer(pResult);+	memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));+	ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);++	crypto_kdone(krp);++	return;++}++/* Name        : icp_ocfDrvModExpCRTCallBack+ *+ * Description : When this function returns it signifies that the LAC+ * component has completed the Mod Exp CRT operation.+ */+static void+icp_ocfDrvModExpCRTCallBack(void *callbackTag,+			    CpaStatus status,+			    void *pOpData, CpaFlatBuffer * pOutputData)+{+	struct cryptkop *krp = NULL;+	CpaCyRsaDecryptOpData *pDecryptData = NULL;++	if (NULL == callbackTag) {+		DPRINTK("%s(): Invalid input parameters - "+			"callbackTag data is NULL\n", __FUNCTION__);+		return;+	}++	krp = (struct cryptkop *)callbackTag;++	if (NULL == pOpData) {+		DPRINTK("%s(): Invalid input parameters - "+			"Operation Data is NULL\n", __FUNCTION__);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}+	pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;++	if (NULL == pOutputData) {+		DPRINTK("%s(): Invalid input parameter - "+			"pOutputData is NULL\n", __FUNCTION__);+		memset(pDecryptData->pRecipientPrivateKey, 0,+		       sizeof(CpaCyRsaPrivateKey));+		ICP_CACHE_FREE(drvRSAPrivateKey_zone,+			       pDecryptData->pRecipientPrivateKey);+		memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));+		ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}++	if (CPA_STATUS_SUCCESS == status) {+		krp->krp_status = CRYPTO_OP_SUCCESS;+	} else {+		APRINTK("%s(): LAC Mod Exp CRT operation failed - "+			"Operation Status = %d\n", __FUNCTION__, status);+		krp->krp_status = ECANCELED;+	}++	icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);++	icp_ocfDrvFreeFlatBuffer(pOutputData);+	memset(pDecryptData->pRecipientPrivateKey, 0,+	       sizeof(CpaCyRsaPrivateKey));+	ICP_CACHE_FREE(drvRSAPrivateKey_zone,+		       pDecryptData->pRecipientPrivateKey);+	memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));+	ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);++	crypto_kdone(krp);++	return;+}++/* Name        : icp_ocfDrvDsaRSSignCallBack+ *+ * Description : When this function returns it signifies that the LAC+ * component has completed the DSA RS sign operation.+ */+static void+icp_ocfDrvDsaRSSignCallBack(void *callbackTag,+			    CpaStatus status,+			    void *pOpData,+			    CpaBoolean protocolStatus,+			    CpaFlatBuffer * pR, CpaFlatBuffer * pS)+{+	struct cryptkop *krp = NULL;+	CpaCyDsaRSSignOpData *pSignData = NULL;++	if (NULL == callbackTag) {+		DPRINTK("%s(): Invalid input parameters - "+			"callbackTag data is NULL\n", __FUNCTION__);+		return;+	}++	krp = (struct cryptkop *)callbackTag;++	if (NULL == pOpData) {+		DPRINTK("%s(): Invalid input parameters - "+			"Operation Data is NULL\n", __FUNCTION__);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}+	pSignData = (CpaCyDsaRSSignOpData *) pOpData;++	if (NULL == pR) {+		DPRINTK("%s(): Invalid input parameter - "+			"pR sign is NULL\n", __FUNCTION__);+		icp_ocfDrvFreeFlatBuffer(pS);+		ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}++	if (NULL == pS) {+		DPRINTK("%s(): Invalid input parameter - "+			"pS sign is NULL\n", __FUNCTION__);+		icp_ocfDrvFreeFlatBuffer(pR);+		ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}++	if (CPA_STATUS_SUCCESS != status) {+		APRINTK("%s(): LAC DSA RS Sign operation failed - "+			"Operation Status = %d\n", __FUNCTION__, status);+		krp->krp_status = ECANCELED;+	} else {+		krp->krp_status = CRYPTO_OP_SUCCESS;++		if (CPA_TRUE != protocolStatus) {+			DPRINTK("%s(): LAC DSA RS Sign operation failed due "+				"to protocol error\n", __FUNCTION__);+			krp->krp_status = EIO;+		}+	}++	/* Swap bytes only when the callback status is successful and+	   protocolStatus is set to true */+	if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {+		icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);+		icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);+	}++	icp_ocfDrvFreeFlatBuffer(pR);+	icp_ocfDrvFreeFlatBuffer(pS);+	memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);+	ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);+	memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));+	ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);+	crypto_kdone(krp);++	return;+}++/* Name        : icp_ocfDrvDsaVerifyCallback+ *+ * Description : When this function returns it signifies that the LAC+ * component has completed the DSA Verify operation.+ */+static void+icp_ocfDrvDsaVerifyCallBack(void *callbackTag,+			    CpaStatus status,+			    void *pOpData, CpaBoolean verifyStatus)+{++	struct cryptkop *krp = NULL;+	CpaCyDsaVerifyOpData *pVerData = NULL;++	if (NULL == callbackTag) {+		DPRINTK("%s(): Invalid input parameters - "+			"callbackTag data is NULL\n", __FUNCTION__);+		return;+	}++	krp = (struct cryptkop *)callbackTag;++	if (NULL == pOpData) {+		DPRINTK("%s(): Invalid input parameters - "+			"Operation Data is NULL\n", __FUNCTION__);+		krp->krp_status = ECANCELED;+		crypto_kdone(krp);+		return;+	}+	pVerData = (CpaCyDsaVerifyOpData *) pOpData;++	if (CPA_STATUS_SUCCESS != status) {+		APRINTK("%s(): LAC DSA Verify operation failed - "+			"Operation Status = %d\n", __FUNCTION__, status);+		krp->krp_status = ECANCELED;+	} else {+		krp->krp_status = CRYPTO_OP_SUCCESS;++		if (CPA_TRUE != verifyStatus) {+			DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);+			krp->krp_status = EIO;+		}+	}++	/* Swap bytes only when the callback status is successful and+	   verifyStatus is set to true */+	/*Just swapping back the key values for now. Possibly all+	   swapped buffers need to be reverted */+	if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {+		icp_ocfDrvSwapBytes(pVerData->R.pData,+				    pVerData->R.dataLenInBytes);+		icp_ocfDrvSwapBytes(pVerData->S.pData,+				    pVerData->S.dataLenInBytes);+	}++	memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));+	ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);+	crypto_kdone(krp);++	return;+}diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.36/crypto/ocf/ep80579/icp_common.c--- linux-2.6.36.orig/crypto/ocf/ep80579/icp_common.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ep80579/icp_common.c	2010-11-09 20:28:04.612495446 +0100@@ -0,0 +1,773 @@+/*************************************************************************+ *+ * This file is provided under a dual BSD/GPLv2 license.  When using or + *   redistributing this file, you may do so under either license.+ * + *   GPL LICENSE SUMMARY+ * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of version 2 of the GNU General Public License as+ *   published by the Free Software Foundation.+ * + *   This program is distributed in the hope that it will be useful, but + *   WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *   General Public License for more details.+ * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.+ *   The full GNU General Public License is included in this distribution + *   in the file called LICENSE.GPL.+ * + *   Contact Information:+ *   Intel Corporation+ * + *   BSD LICENSE + * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ *   All rights reserved.+ * + *   Redistribution and use in source and binary forms, with or without + *   modification, are permitted provided that the following conditions + *   are met:+ * + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer.+ *     * Redistributions in binary form must reproduce the above copyright + *       notice, this list of conditions and the following disclaimer in + *       the documentation and/or other materials provided with the + *       distribution.+ *     * Neither the name of Intel Corporation nor the names of its + *       contributors may be used to endorse or promote products derived + *       from this software without specific prior written permission.+ * + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ * + * + *  version: Security.L.1.0.2-229+ *+ ***************************************************************************/++/*+ * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the + * crypto.+ *+ * This driver requires the ICP Access Library that is available from Intel in+ * order to operate.+ */++#include "icp_ocf.h"++#define ICP_OCF_COMP_NAME                       "ICP_OCF"+#define ICP_OCF_VER_MAIN                        (2)+#define ICP_OCF_VER_MJR                         (1)+#define ICP_OCF_VER_MNR                         (0)++#define MAX_DEREG_RETRIES                       (100)+#define DEFAULT_DEREG_RETRIES 			(10)+#define DEFAULT_DEREG_DELAY_IN_JIFFIES		(10)++/* This defines the maximum number of sessions possible between OCF+   and the OCF EP80579 Driver. If set to zero, there is no limit. */+#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT    (0)+#define NUM_SUPPORTED_CAPABILITIES              (21)++/*Slab zone names*/+#define ICP_SESSION_DATA_NAME   "icp_ocf.SesDat"+#define ICP_OP_DATA_NAME        "icp_ocf.OpDat"+#define ICP_DH_NAME             "icp_ocf.DH"+#define ICP_MODEXP_NAME         "icp_ocf.ModExp"+#define ICP_RSA_DECRYPT_NAME    "icp_ocf.RSAdec"+#define ICP_RSA_PKEY_NAME       "icp_ocf.RSApk"+#define ICP_DSA_SIGN_NAME       "icp_ocf.DSAsg"+#define ICP_DSA_VER_NAME        "icp_ocf.DSAver"+#define ICP_RAND_VAL_NAME       "icp_ocf.DSArnd"+#define ICP_FLAT_BUFF_NAME      "icp_ocf.FB"++/*Slabs zones*/+icp_kmem_cache drvSessionData_zone = NULL;+icp_kmem_cache drvOpData_zone = NULL;+icp_kmem_cache drvDH_zone = NULL;+icp_kmem_cache drvLnModExp_zone = NULL;+icp_kmem_cache drvRSADecrypt_zone = NULL;+icp_kmem_cache drvRSAPrivateKey_zone = NULL;+icp_kmem_cache drvDSARSSign_zone = NULL;+icp_kmem_cache drvDSARSSignKValue_zone = NULL;+icp_kmem_cache drvDSAVerify_zone = NULL;++/*Slab zones for flatbuffers and bufferlist*/+icp_kmem_cache drvFlatBuffer_zone = NULL;++static inline int icp_cache_null_check(void)+{+	return (drvSessionData_zone && drvOpData_zone+		&& drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone+		&& drvRSAPrivateKey_zone && drvDSARSSign_zone+		&& drvDSARSSign_zone && drvDSARSSignKValue_zone+		&& drvDSAVerify_zone && drvFlatBuffer_zone);+}++/*Function to free all allocated slab caches before exiting the module*/+static void icp_ocfDrvFreeCaches(void);++int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;++/* Module parameter - gives the number of times LAC deregistration shall be+   re-tried */+int num_dereg_retries = DEFAULT_DEREG_RETRIES;++/* Module parameter - gives the delay time in jiffies before a LAC session +   shall be attempted to be deregistered again */+int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;++/* Module parameter - gives the maximum number of sessions possible between+   OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/+int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;++/* This is set when the module is removed from the system, no further+   processing can take place if this is set */+icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);++/* This is used to show how many lac sessions were not deregistered*/+icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);++/* This is used to track the number of registered sessions between OCF and+ * and the OCF EP80579 driver, when max_session is set to value other than+ * zero. This ensures that the max_session set for the OCF and the driver+ * is equal to the LAC registered sessions */+icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);++/* Head of linked list used to store session data */+icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;+icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;++icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;++/*Below pointer is only used in linux, FreeBSD uses the name to+create its own variable name*/+icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;+ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);++struct icp_drvBuffListInfo defBuffListInfo;++/* Name        : icp_ocfDrvInit+ *+ * Description : This function will register all the symmetric and asymmetric+ * functionality that will be accelerated by the hardware. It will also+ * get a unique driver ID from the OCF and initialise all slab caches+ */+ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)+{+	int ocfStatus = 0;++	IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,+		ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);++	if (MAX_DEREG_RETRIES < num_dereg_retries) {+		EPRINTK("Session deregistration retry count set to greater "+			"than %d", MAX_DEREG_RETRIES);+		icp_module_return_code(EINVAL);+	}++	/* Initialize and Start the Cryptographic component */+	if (CPA_STATUS_SUCCESS !=+	    cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {+		EPRINTK("Failed to initialize and start the instance "+			"of the Cryptographic component.\n");+		return icp_module_return_code(EINVAL);+	}++	icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);++	/* Set the default size of BufferList to allocate */+	memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));+	if (ICP_OCF_DRV_STATUS_SUCCESS !=+	    icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,+					&defBuffListInfo)) {+		EPRINTK("Failed to get bufferlist memory info.\n");+		return icp_module_return_code(ENOMEM);+	}++	/*Register OCF EP80579 Driver with OCF */+	icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();++	if (icp_ocfDrvDriverId < 0) {+		EPRINTK("%s : ICP driver failed to register with OCF!\n",+			__FUNCTION__);+		return icp_module_return_code(ENODEV);+	}++	/*Create all the slab caches used by the OCF EP80579 Driver */+	drvSessionData_zone =+	    ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);++	/* +	 * Allocation of the OpData includes the allocation space for meta data.+	 * The memory after the opData structure is reserved for this meta data.+	 */+	drvOpData_zone =+	    icp_kmem_cache_create(ICP_OP_DATA_NAME,+				  sizeof(struct icp_drvOpData) ++				  defBuffListInfo.metaSize,+				  ICP_KERNEL_CACHE_ALIGN,+				  ICP_KERNEL_CACHE_NOINIT);++	drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);++	drvLnModExp_zone =+	    ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);++	drvRSADecrypt_zone =+	    ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);++	drvRSAPrivateKey_zone =+	    ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);++	drvDSARSSign_zone =+	    ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);++	/*too awkward to use a macro here */+	drvDSARSSignKValue_zone =+	    ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,+			     DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);++	drvDSAVerify_zone =+	    ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);++	drvFlatBuffer_zone =+	    ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);++	if (0 == icp_cache_null_check()) {+		icp_ocfDrvFreeCaches();+		EPRINTK("%s() line %d: Not enough memory!\n",+			__FUNCTION__, __LINE__);+		return ENOMEM;+	}++	/* Register the ICP symmetric crypto support. */+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,+			     ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,+			     ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);+	ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,+			     ocfStatus);++	/* Register the ICP asymmetric algorithm support */+	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,+			      ocfStatus);+	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);+	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);+	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);+	ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);++	/* Register the ICP random number generator support */+	ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,+			      icp_ocfDrvReadRandom, NULL, ocfStatus);++	if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {+		DPRINTK("%s: Failed to register any device capabilities\n",+			__FUNCTION__);+		icp_ocfDrvFreeCaches();+		icp_ocfDrvDriverId = INVALID_DRIVER_ID;+		return icp_module_return_code(ECANCELED);+	}++	DPRINTK("%s: Registered %d of %d device capabilities\n",+		__FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);++	/*Session data linked list used during module exit */+	ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);+	ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);++	ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");+	if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {+		EPRINTK("%s: Failed to create single "+			"thread workqueue\n", __FUNCTION__);+		icp_ocfDrvFreeCaches();+		icp_ocfDrvDriverId = INVALID_DRIVER_ID;+		return icp_module_return_code(ENOMEM);+	}++	return icp_module_return_code(0);+}++/* Name        : icp_ocfDrvExit+ *+ * Description : This function will deregister all the symmetric sessions+ * registered with the LAC component. It will also deregister all symmetric+ * and asymmetric functionality that can be accelerated by the hardware via OCF+ * and random number generation if it is enabled.+ */+ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)+{+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	struct icp_drvSessionData *sessionData = NULL;+	struct icp_drvSessionData *tempSessionData = NULL;+	int i, remaining_delay_time_in_jiffies = 0;++	/* For FreeBSD the invariant macro below makes function to return     */+	/* with EBUSY value in the case of any session which has been regi-   */+	/* stered with LAC not being deregistered.                            */+	/* The Linux implementation is empty since it is purely to compensate */+	/* for a limitation of the FreeBSD 7.1 Opencrypto framework.          */++    ICP_MODULE_EXIT_INV();++	/* There is a possibility of a process or new session command being   */+	/* sent before this variable is incremented. The aim of this variable */+	/* is to stop a loop of calls creating a deadlock situation which     */+	/* would prevent the driver from exiting.                             */+	icp_atomic_set(&icp_ocfDrvIsExiting, 1);++	/*Existing sessions will be routed to another driver after these calls */+	crypto_unregister_all(icp_ocfDrvDriverId);+	crypto_runregister_all(icp_ocfDrvDriverId);++	if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {+		DPRINTK("%s: workqueue already "+			"destroyed, therefore module exit "+			" function already called. Exiting.\n", __FUNCTION__);+		return ICP_MODULE_EXIT_FUNC_RETURN_VAL;+	}+	/*If any sessions are waiting to be deregistered, do that. This also +	   flushes the work queue */+	ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);++	/*ENTER CRITICAL SECTION */+	icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);++	ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,+				     &icp_ocfDrvGlobalSymListHead, listNode) {+		for (i = 0; i < num_dereg_retries; i++) {+			/*No harm if bad input - LAC will handle error cases */+			if (ICP_SESSION_RUNNING == tempSessionData->inUse) {+				lacStatus =+				    cpaCySymRemoveSession+				    (CPA_INSTANCE_HANDLE_SINGLE,+				     tempSessionData->sessHandle);+				if (CPA_STATUS_SUCCESS == lacStatus) {+					/* Succesfully deregistered */+					break;+				} else if (CPA_STATUS_RETRY != lacStatus) {+					icp_atomic_inc+					    (&lac_session_failed_dereg_count);+					break;+				}++				/*schedule_timout returns the time left for completion if +				 * this task is set to TASK_INTERRUPTIBLE */+				remaining_delay_time_in_jiffies =+				    dereg_retry_delay_in_jiffies;+				while (0 > remaining_delay_time_in_jiffies) {+					remaining_delay_time_in_jiffies =+					    icp_schedule_timeout+					    (&icp_ocfDrvSymSessInfoListSpinlock,+					     remaining_delay_time_in_jiffies);+				}++				DPRINTK+				    ("%s(): Retry %d to deregistrate the session\n",+				     __FUNCTION__, i);+			}+		}++		/*remove from current list */+		ICP_LIST_DEL(tempSessionData, listNode);+		/*add to free mem linked list */+		ICP_LIST_ADD(tempSessionData,+			     &icp_ocfDrvGlobalSymListHead_FreeMemList,+			     listNode);++	}++	/*EXIT CRITICAL SECTION */+	icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);++	/*set back to initial values */+	sessionData = NULL;+	/*still have a reference in our list! */+	tempSessionData = NULL;+	/*free memory */++	ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,+				     &icp_ocfDrvGlobalSymListHead_FreeMemList,+				     listNode) {++		ICP_LIST_DEL(tempSessionData, listNode);+		/* Free allocated CpaCySymSessionCtx */+		if (NULL != tempSessionData->sessHandle) {+			icp_kfree(tempSessionData->sessHandle);+		}+		memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));+		ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);+	}++	if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {+		DPRINTK("%s(): %d LAC sessions were not deregistered "+			"correctly. This is not a clean exit! \n",+			__FUNCTION__,+			icp_atomic_read(&lac_session_failed_dereg_count));+	}++	icp_ocfDrvFreeCaches();+	icp_ocfDrvDriverId = INVALID_DRIVER_ID;++	icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);++	/* Shutdown the Cryptographic component */+	lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);+	if (CPA_STATUS_SUCCESS != lacStatus) {+		DPRINTK("%s(): Failed to stop instance of the "+			"Cryptographic component.(status == %d)\n",+			__FUNCTION__, lacStatus);+	}++	return ICP_MODULE_EXIT_FUNC_RETURN_VAL;+}++/* Name        : icp_ocfDrvFreeCaches+ *+ * Description : This function deregisters all slab caches+ */+static void icp_ocfDrvFreeCaches(void)+{+	icp_atomic_set(&icp_ocfDrvIsExiting, 1);++	/*Sym Zones */+	ICP_CACHE_DESTROY(drvSessionData_zone);+	ICP_CACHE_DESTROY(drvOpData_zone);++	/*Asym zones */+	ICP_CACHE_DESTROY(drvDH_zone);+	ICP_CACHE_DESTROY(drvLnModExp_zone);+	ICP_CACHE_DESTROY(drvRSADecrypt_zone);+	ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);+	ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);+	ICP_CACHE_DESTROY(drvDSARSSign_zone);+	ICP_CACHE_DESTROY(drvDSAVerify_zone);++	/*FlatBuffer and BufferList Zones */+	ICP_CACHE_DESTROY(drvFlatBuffer_zone);++}++/* Name        : icp_ocfDrvDeregRetry+ *+ * Description : This function will try to farm the session deregistration+ * off to a work queue. If it fails, nothing more can be done and it+ * returns an error+ */+int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)+{+	struct icp_ocfDrvFreeLacSession *workstore = NULL;++	DPRINTK("%s(): Retry - Deregistering session (%p)\n",+		__FUNCTION__, sessionToDeregister);++	/*make sure the session is not available to be allocated during this+	   process */+	icp_atomic_inc(&lac_session_failed_dereg_count);++	/*Farm off to work queue */+	workstore =+	    icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);+	if (NULL == workstore) {+		DPRINTK("%s(): unable to free session - no memory available "+			"for work queue\n", __FUNCTION__);+		return ENOMEM;+	}++	workstore->sessionToDeregister = sessionToDeregister;++	icp_init_work(&(workstore->work),+		      icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);++	ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,+			      &(workstore->work));++	return ICP_OCF_DRV_STATUS_SUCCESS;++}++/* Name        : icp_ocfDrvDeferedFreeLacSessionProcess+ *+ * Description : This function will retry (module input parameter)+ * 'num_dereg_retries' times to deregister any symmetric session that recieves a+ * CPA_STATUS_RETRY message from the LAC component. This function is run in+ * Thread context because it is called from a worker thread+ */+void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)+{+	struct icp_ocfDrvFreeLacSession *workstore = NULL;+	CpaCySymSessionCtx sessionToDeregister = NULL;+	int i = 0;+	int remaining_delay_time_in_jiffies = 0;+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;++	workstore = (struct icp_ocfDrvFreeLacSession *)arg;+	if (NULL == workstore) {+		DPRINTK("%s() function called with null parameter \n",+			__FUNCTION__);+		return;+	}++	sessionToDeregister = workstore->sessionToDeregister;+	icp_kfree(workstore);++	/*if exiting, give deregistration one more blast only */+	if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {+		lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,+						  sessionToDeregister);++		if (lacStatus != CPA_STATUS_SUCCESS) {+			DPRINTK("%s() Failed to Dereg LAC session %p "+				"during module exit\n", __FUNCTION__,+				sessionToDeregister);+			return;+		}++		icp_atomic_dec(&lac_session_failed_dereg_count);+		return;+	}++	for (i = 0; i <= num_dereg_retries; i++) {+		lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,+						  sessionToDeregister);++		if (lacStatus == CPA_STATUS_SUCCESS) {+			icp_atomic_dec(&lac_session_failed_dereg_count);+			return;+		}+		if (lacStatus != CPA_STATUS_RETRY) {+			DPRINTK("%s() Failed to deregister session - lacStatus "+				" = %d", __FUNCTION__, lacStatus);+			break;+		}++		/*schedule_timout returns the time left for completion if this+		   task is set to TASK_INTERRUPTIBLE */+		remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;+		while (0 < remaining_delay_time_in_jiffies) {+			remaining_delay_time_in_jiffies =+			    icp_schedule_timeout(NULL,+						 remaining_delay_time_in_jiffies);+		}++	}++	DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);+	DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,+		icp_atomic_read(&lac_session_failed_dereg_count));+}++/* Name        : icp_ocfDrvPtrAndLenToFlatBuffer + *+ * Description : This function converts a "pointer and length" buffer + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.+ *+ * This function assumes that the data passed in are valid.+ */+inline void+icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,+				CpaFlatBuffer * pFlatBuffer)+{+	pFlatBuffer->pData = pData;+	pFlatBuffer->dataLenInBytes = len;+}++/* Name        : icp_ocfDrvPtrAndLenToBufferList+ *+ * Description : This function converts a "pointer and length" buffer+ * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.+ *+ * This function assumes that the data passed in are valid.+ */+inline void+icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,+				CpaBufferList * pBufferList)+{+	pBufferList->numBuffers = 1;+	pBufferList->pBuffers->pData = pDataIn;+	pBufferList->pBuffers->dataLenInBytes = length;+}++/* Name        : icp_ocfDrvBufferListToPtrAndLen+ *+ * Description : This function converts Fredericksburg Scatter/Gather Buffer+ * (CpaBufferList) format to a "pointer and length" buffer structure.+ *+ * This function assumes that the data passed in are valid.+ */+inline void+icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,+				void **ppDataOut, uint32_t * pLength)+{+	*ppDataOut = pBufferList->pBuffers->pData;+	*pLength = pBufferList->pBuffers->dataLenInBytes;+}++/* Name        : icp_ocfDrvBufferListMemInfo+ *+ * Description : This function will set the number of flat buffers in + * bufferlist, the size of memory to allocate for the pPrivateMetaData + * member of the CpaBufferList.+ */+int+icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,+			    struct icp_drvBuffListInfo *buffListInfo)+{+	buffListInfo->numBuffers = numBuffers;++	if (CPA_STATUS_SUCCESS !=+	    cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,+				       buffListInfo->numBuffers,+				       &(buffListInfo->metaSize))) {+		EPRINTK("%s() Failed to get buffer list meta size.\n",+			__FUNCTION__);+		return ICP_OCF_DRV_STATUS_FAIL;+	}++	return ICP_OCF_DRV_STATUS_SUCCESS;+}++/* Name        : icp_ocfDrvFreeFlatBuffer+ *+ * Description : This function will deallocate flat buffer.+ */+inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)+{+	if (pFlatBuffer != NULL) {+		memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));+		ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);+	}+}++/* Name        : icp_ocfDrvAllocMetaData+ *+ * Description : This function will allocate memory for the+ * pPrivateMetaData member of CpaBufferList.+ */+inline int+icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,+			struct icp_drvOpData *pOpData)+{+	Cpa32U metaSize = 0;++	if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {+		uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;++		if (0 == defBuffListInfo.metaSize) {+			pBufferList->pPrivateMetaData = NULL;+			return ICP_OCF_DRV_STATUS_SUCCESS;+		}+		/*+		 * The meta data allocation has been included as part of the +		 * op data.  It has been pre-allocated in memory just after the+		 * icp_drvOpData structure.+		 */+		pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr ++							 sizeof(struct+								icp_drvOpData));+	} else {+		if (CPA_STATUS_SUCCESS !=+		    cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,+					       pBufferList->numBuffers,+					       &metaSize)) {+			EPRINTK("%s() Failed to get buffer list meta size.\n",+				__FUNCTION__);+			return ICP_OCF_DRV_STATUS_FAIL;+		}++		if (0 == metaSize) {+			pBufferList->pPrivateMetaData = NULL;+			return ICP_OCF_DRV_STATUS_SUCCESS;+		}++		pBufferList->pPrivateMetaData =+		    icp_kmalloc(metaSize, ICP_M_NOWAIT);+	}+	if (NULL == pBufferList->pPrivateMetaData) {+		EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",+			__FUNCTION__);+		return ICP_OCF_DRV_STATUS_FAIL;+	}++	return ICP_OCF_DRV_STATUS_SUCCESS;+}++/* Name        : icp_ocfDrvFreeMetaData+ *+ * Description : This function will deallocate pPrivateMetaData memory.+ */+inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)+{+	if (NULL == pBufferList->pPrivateMetaData) {+		return;+	}++	/*+	 * Only free the meta data if the BufferList has more than +	 * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.+	 * Otherwise, the meta data shall be freed when the icp_drvOpData is+	 * freed.+	 */+	if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {+		icp_kfree(pBufferList->pPrivateMetaData);+	}+}++/* Module declaration, init and exit functions */+ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);+ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");+ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);+ICP_MODULE_LICENSE("Dual BSD/GPL");+ICP_MODULE_AUTHOR("Intel");++/* Module parameters */+ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,+		     "Number of times to retry LAC Sym Session Deregistration. "+		     "Default 10, Max 100");+ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "+		     "(added to a schedule() function call) before a LAC Sym "+		     "Session Dereg is retried. Default 10");+ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,+		     "This sets the maximum number of sessions "+		     "between OCF and this driver. If this value is set to zero,"+		     "max session count checking is disabled. Default is zero(0)");++/* Module dependencies */+#define MODULE_MIN_VER	1+#define CRYPTO_MAX_VER	3+#define LAC_MAX_VER	2++ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,+		  CRYPTO_MAX_VER);+ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,+		  CRYPTO_MAX_VER);+ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,+		  LAC_MAX_VER);diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.36/crypto/ocf/ep80579/icp_ocf.h--- linux-2.6.36.orig/crypto/ocf/ep80579/icp_ocf.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ep80579/icp_ocf.h	2010-11-09 20:28:04.662495462 +0100@@ -0,0 +1,376 @@+/***************************************************************************+ *+ * This file is provided under a dual BSD/GPLv2 license.  When using or + *   redistributing this file, you may do so under either license.+ * + *   GPL LICENSE SUMMARY+ * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of version 2 of the GNU General Public License as+ *   published by the Free Software Foundation.+ * + *   This program is distributed in the hope that it will be useful, but + *   WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *   General Public License for more details.+ * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.+ *   The full GNU General Public License is included in this distribution + *   in the file called LICENSE.GPL.+ * + *   Contact Information:+ *   Intel Corporation+ * + *   BSD LICENSE + * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ *   All rights reserved.+ * + *   Redistribution and use in source and binary forms, with or without + *   modification, are permitted provided that the following conditions + *   are met:+ * + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer.+ *     * Redistributions in binary form must reproduce the above copyright + *       notice, this list of conditions and the following disclaimer in + *       the documentation and/or other materials provided with the + *       distribution.+ *     * Neither the name of Intel Corporation nor the names of its + *       contributors may be used to endorse or promote products derived + *       from this software without specific prior written permission.+ * + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ * + * + *  version: Security.L.1.0.2-229+ *+ ***************************************************************************/++/*+ * OCF driver header file for the Intel ICP processor.+ */++#ifndef ICP_OCF_H_+#define ICP_OCF_H_++#include <cpa.h>+#include <cpa_cy_im.h>+#include <cpa_cy_sym.h>+#include <cpa_cy_rand.h>+#include <cpa_cy_dh.h>+#include <cpa_cy_rsa.h>+#include <cpa_cy_ln.h>+#include <cpa_cy_common.h>+#include <cpa_cy_dsa.h>++#include "icp_os.h"++#define NUM_BITS_IN_BYTE (8)+#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)+#define INVALID_DRIVER_ID (-1)+#define RETURN_RAND_NUM_GEN_FAILED (-1)++/*This is the max block cipher initialisation vector*/+#define MAX_IV_LEN_IN_BYTES (20)+/*This is used to check whether the OCF to this driver session limit has+  been disabled*/+#define NO_OCF_TO_DRV_MAX_SESSIONS		(0)++/*OCF values mapped here*/+#define ICP_SHA1_DIGEST_SIZE_IN_BYTES 		(SHA1_HASH_LEN)+#define ICP_SHA256_DIGEST_SIZE_IN_BYTES 	(SHA2_256_HASH_LEN)+#define ICP_SHA384_DIGEST_SIZE_IN_BYTES 	(SHA2_384_HASH_LEN)+#define ICP_SHA512_DIGEST_SIZE_IN_BYTES 	(SHA2_512_HASH_LEN)+#define ICP_MD5_DIGEST_SIZE_IN_BYTES 		(MD5_HASH_LEN)+#define ARC4_COUNTER_LEN 			(ARC4_BLOCK_LEN)++#define OCF_REGISTRATION_STATUS_SUCCESS 	(0)+#define OCF_ZERO_FUNCTIONALITY_REGISTERED 	(0)+#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR 	(0)+#define ICP_OCF_DRV_STATUS_SUCCESS 		(0)+#define ICP_OCF_DRV_STATUS_FAIL 		(1)++/*Turn on/off debug options*/+#define ICP_OCF_PRINT_DEBUG_MESSAGES		(0)+#define ICP_OCF_PRINT_KERN_ALERT		(1)+#define ICP_OCF_PRINT_KERN_ERRS			(1)++#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1+#define DPRINTK(args...)      \+{			      \+                ICP_IPRINTK(args); \+}++#else				//ICP_OCF_PRINT_DEBUG_MESSAGES == 1++#define DPRINTK(args...)++#endif				//ICP_OCF_PRINT_DEBUG_MESSAGES == 1++#if ICP_OCF_PRINT_KERN_ALERT == 1+#define APRINTK(args...)      						\+{			      						\+       ICP_APRINTK(args);						\+}++#else				//ICP_OCF_PRINT_KERN_ALERT == 1++#define APRINTK(args...)++#endif				//ICP_OCF_PRINT_KERN_ALERT == 1++#if ICP_OCF_PRINT_KERN_ERRS == 1+#define EPRINTK(args...)      \+{			      \+       ICP_EPRINTK(args); \+}++#else				//ICP_OCF_PRINT_KERN_ERRS == 1++#define EPRINTK(args...)++#endif				//ICP_OCF_PRINT_KERN_ERRS == 1++#define IPRINTK(args...)      \+{			      \+      ICP_IPRINTK(args); \+}++/*DSA Prime Q size in bytes (as defined in the standard) */+#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES	(20)++#define BITS_TO_BYTES(bytes, bits) 					\+	bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE++typedef enum {+	ICP_OCF_DRV_ALG_CIPHER = 0,+	ICP_OCF_DRV_ALG_HASH+} icp_ocf_drv_alg_type_t;++typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,+		      icp_drvSessionData) icp_drvSessionListHead_t;++/*Values used to derisk chances of performs being called against+deregistered sessions (for which the slab page has been reclaimed)+This is not a fix - since page frames are reclaimed from a slab, one cannot+rely on that memory not being re-used by another app.*/+typedef enum {+	ICP_SESSION_INITIALISED = 0x5C5C5C,+	ICP_SESSION_RUNNING = 0x005C00,+	ICP_SESSION_DEREGISTERED = 0xC5C5C5+} usage_derisk;++/* This struct is required for deferred session+ deregistration as a work queue function can+ only have one argument*/+struct icp_ocfDrvFreeLacSession {+	CpaCySymSessionCtx sessionToDeregister;+	icp_workstruct work;+};++/*+This is the OCF<->OCF_DRV session object:++1.listNode+  The first member is a listNode. These session objects are added to a linked+  list in order to make it easier to remove them all at session exit time.++2.inUse+  The second member is used to give the session object state and derisk the+  possibility of OCF batch calls executing against a deregistered session (as+  described above).++3.sessHandle+  The third member is a LAC<->OCF_DRV session handle (initialised with the first+  perform request for that session).++4.lacSessCtx+  The fourth is the LAC session context. All the parameters for this structure+  are only known when the first perform request for this session occurs. That is+  why the OCF EP80579 Driver only registers a new LAC session at perform time+*/+struct icp_drvSessionData {+	ICP_LIST_ENTRY(icp_drvSessionData) listNode;+	usage_derisk inUse;+	CpaCySymSessionCtx sessHandle;+	CpaCySymSessionSetupData lacSessCtx;+};++/* These are all defined in icp_common.c */+extern icp_atomic_t lac_session_failed_dereg_count;+extern icp_atomic_t icp_ocfDrvIsExiting;+extern icp_atomic_t num_ocf_to_drv_registered_sessions;++extern int32_t icp_ocfDrvDriverId;++extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;+extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;+extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;+extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;++/*Slab zones for symettric functionality, instantiated in icp_common.c*/+extern icp_kmem_cache drvSessionData_zone;+extern icp_kmem_cache drvOpData_zone;++/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/+extern icp_kmem_cache drvDH_zone;+extern icp_kmem_cache drvLnModExp_zone;+extern icp_kmem_cache drvRSADecrypt_zone;+extern icp_kmem_cache drvRSAPrivateKey_zone;+extern icp_kmem_cache drvDSARSSign_zone;+extern icp_kmem_cache drvDSARSSignKValue_zone;+extern icp_kmem_cache drvDSAVerify_zone;++/* Module parameters defined in icp_cpmmon.c*/++/* Module parameters - gives the number of times LAC deregistration shall be+   re-tried */+extern int num_dereg_retries;++/* Module parameter - gives the delay time in jiffies before a LAC session +   shall be attempted to be deregistered again */+extern int dereg_retry_delay_in_jiffies;++/* Module parameter - gives the maximum number of sessions possible between+   OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/+extern int max_sessions;++/*Slab zones for flatbuffers and bufferlist*/+extern icp_kmem_cache drvFlatBuffer_zone;++#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS     (16)++struct icp_drvBuffListInfo {+	Cpa16U numBuffers;+	Cpa32U metaSize;+	Cpa32U metaOffset;+	Cpa32U buffListSize;+};++extern struct icp_drvBuffListInfo defBuffListInfo;++/* This struct is used to keep a reference to the relevant node in the list+   of sessionData structs, to the buffer type required by OCF and to the OCF+   provided crp struct that needs to be returned. All this info is needed in+   the callback function.*/+struct icp_drvOpData {+	CpaCySymOpData lacOpData;+	uint32_t digestSizeInBytes;+	struct cryptop *crp;+	uint8_t bufferType;+	uint8_t ivData[MAX_IV_LEN_IN_BYTES];+	uint16_t numBufferListArray;+	CpaBufferList srcBuffer;+	CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];+	CpaBoolean verifyResult;+};++/* Create a new session between OCF and this driver*/+int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,+			 struct cryptoini *cri);++/* Free a session between this driver and the Quick Assist Framework*/+int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);++/* Defer freeing a Quick Assist session*/+void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);++/* Process OCF cryptographic request for a symmetric algorithm*/+int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);++/* Process OCF cryptographic request for an asymmetric algorithm*/+int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);++/* Populate a buffer with random data*/+int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);++/* Retry Quick Assist session deregistration*/+int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);++/* Convert an OS scatter gather list to a CPA buffer list*/+int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,+				     CpaBufferList * bufferList);++/* Convert a CPA buffer list to an OS scatter gather list*/+int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,+				     icp_packet_buffer_t ** pPacketBuffer);++/* Get the number of buffers in an OS scatter gather list*/+uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);++/* Convert a single OS buffer to a CPA Flat Buffer*/+void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,+					    CpaFlatBuffer * pFlatBuffer);++/* Add pointer and length to a CPA Flat Buffer structure*/+void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,+				     CpaFlatBuffer * pFlatBuffer);++/* Convert pointer and length values to a CPA buffer list*/+void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,+				     CpaBufferList * pBufferList);++/* Convert a CPA buffer list to pointer and length values*/+void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,+				     void **ppDataOut, uint32_t * pLength);++/* Set the number of flat buffers in bufferlist and the size of memory+   to allocate for the pPrivateMetaData member of the CpaBufferList.*/+int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,+				struct icp_drvBuffListInfo *buffListInfo);++/* Find pointer position of the digest within an OS scatter gather list*/+uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData+						 *drvOpData,+						 int offsetInBytes,+						 uint32_t digestSizeInBytes);++/*This top level function is used to find a pointer to where a digest is +  stored/needs to be inserted. */+uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,+				     struct cryptodesc *crp_desc);++/* Free a CPA flat buffer*/+void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);++/* This function will allocate memory for the pPrivateMetaData+   member of CpaBufferList. */+int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,+			    struct icp_drvOpData *pOpData);++/* Free data allocated for the pPrivateMetaData+   member of CpaBufferList.*/+void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);++#define ICP_CACHE_CREATE(cache_ID, cache_name) \+	icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\+	ICP_KERNEL_CACHE_NOINIT)++#define ICP_CACHE_FREE(args...) \+	icp_kmem_cache_free (args)++#define ICP_CACHE_DESTROY(slab_zone)\+{\+        if(NULL != slab_zone){\+                icp_kmem_cache_destroy(slab_zone);\+                slab_zone = NULL;\+        }\+}++#endif+/* ICP_OCF_H_ */diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.36/crypto/ocf/ep80579/icp_sym.c--- linux-2.6.36.orig/crypto/ocf/ep80579/icp_sym.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ep80579/icp_sym.c	2010-11-09 20:28:04.702495471 +0100@@ -0,0 +1,1153 @@+/***************************************************************************+ *+ * This file is provided under a dual BSD/GPLv2 license.  When using or + *   redistributing this file, you may do so under either license.+ * + *   GPL LICENSE SUMMARY+ * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of version 2 of the GNU General Public License as+ *   published by the Free Software Foundation.+ * + *   This program is distributed in the hope that it will be useful, but + *   WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + *   General Public License for more details.+ * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.+ *   The full GNU General Public License is included in this distribution + *   in the file called LICENSE.GPL.+ * + *   Contact Information:+ *   Intel Corporation+ * + *   BSD LICENSE + * + *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+ *   All rights reserved.+ * + *   Redistribution and use in source and binary forms, with or without + *   modification, are permitted provided that the following conditions + *   are met:+ * + *     * Redistributions of source code must retain the above copyright + *       notice, this list of conditions and the following disclaimer.+ *     * Redistributions in binary form must reproduce the above copyright + *       notice, this list of conditions and the following disclaimer in + *       the documentation and/or other materials provided with the + *       distribution.+ *     * Neither the name of Intel Corporation nor the names of its + *       contributors may be used to endorse or promote products derived + *       from this software without specific prior written permission.+ * + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ * + * + *  version: Security.L.1.0.2-229+ *+ ***************************************************************************/+/*+ * An OCF module that uses the API for Intel® QuickAssist Technology to do the+ * cryptography.+ *+ * This driver requires the ICP Access Library that is available from Intel in+ * order to operate.+ */++#include "icp_ocf.h"++/*This is the call back function for all symmetric cryptographic processes.+  Its main functionality is to free driver crypto operation structure and to +  call back to OCF*/+static void+icp_ocfDrvSymCallBack(void *callbackTag,+		      CpaStatus status,+		      const CpaCySymOp operationType,+		      void *pOpData,+		      CpaBufferList * pDstBuffer, CpaBoolean verifyResult);++/*This function is used to extract crypto processing information from the OCF+  inputs, so as that it may be passed onto LAC*/+static int+icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,+			   struct cryptodesc *crp_desc);++/*This function checks whether the crp_desc argument pertains to a digest or a+  cipher operation*/+static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);++/*This function copies all the passed in session context information and stores+  it in a LAC context structure*/+static int+icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,+			 CpaCySymSessionSetupData * lacSessCtx);++/*This function is used to free an OCF->OCF_DRV session object*/+static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);++/*max IOV buffs supported in a UIO structure*/+#define NUM_IOV_SUPPORTED		(1)++/* Name        : icp_ocfDrvSymCallBack+ *+ * Description : When this function returns it signifies that the LAC+ * component has completed the relevant symmetric operation. + *+ * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory+ * object was passed to LAC for the cryptographic processing and contains all+ * the relevant information for cleaning up buffer handles etc. so that the+ * OCF EP80579 Driver portion of this crypto operation can be fully completed.+ */+static void+icp_ocfDrvSymCallBack(void *callbackTag,+		      CpaStatus status,+		      const CpaCySymOp operationType,+		      void *pOpData,+		      CpaBufferList * pDstBuffer, CpaBoolean verifyResult)+{+	struct cryptop *crp = NULL;+	struct icp_drvOpData *temp_drvOpData =+	    (struct icp_drvOpData *)callbackTag;+	uint64_t *tempBasePtr = NULL;+	uint32_t tempLen = 0;++	if (NULL == temp_drvOpData) {+		DPRINTK("%s(): The callback from the LAC component"+			" has failed due to Null userOpaque data"+			"(status == %d).\n", __FUNCTION__, status);+		DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);+		return;+	}++	crp = temp_drvOpData->crp;+	crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;++	if (NULL == pOpData) {+		DPRINTK("%s(): The callback from the LAC component"+			" has failed due to Null Symmetric Op data"+			"(status == %d).\n", __FUNCTION__, status);+		crp->crp_etype = ECANCELED;+		crypto_done(crp);+		return;+	}++	if (NULL == pDstBuffer) {+		DPRINTK("%s(): The callback from the LAC component"+			" has failed due to Null Dst Bufferlist data"+			"(status == %d).\n", __FUNCTION__, status);+		crp->crp_etype = ECANCELED;+		crypto_done(crp);+		return;+	}++	if (CPA_STATUS_SUCCESS == status) {++		if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {+			if (ICP_OCF_DRV_STATUS_SUCCESS !=+			    icp_ocfDrvBufferListToPacketBuff(pDstBuffer,+							     (icp_packet_buffer_t+							      **)+							     & (crp->crp_buf))) {+				EPRINTK("%s(): BufferList to SkBuff "+					"conversion error.\n", __FUNCTION__);+				crp->crp_etype = EPERM;+			}+		} else {+			icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,+							(void **)&tempBasePtr,+							&tempLen);+			crp->crp_olen = (int)tempLen;+		}++	} else {+		DPRINTK("%s(): The callback from the LAC component has failed"+			"(status == %d).\n", __FUNCTION__, status);++		crp->crp_etype = ECANCELED;+	}++	if (temp_drvOpData->numBufferListArray >+	    ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {+		icp_kfree(pDstBuffer->pBuffers);+	}+	icp_ocfDrvFreeMetaData(pDstBuffer);+	ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);++	/* Invoke the OCF callback function */+	crypto_done(crp);++	return;+}++/* Name        : icp_ocfDrvNewSession + *+ * Description : This function will create a new Driver<->OCF session+ *+ * Notes : LAC session registration happens during the first perform call.+ * That is the first time we know all information about a given session.+ */+int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,+			 struct cryptoini *cri)+{+	struct icp_drvSessionData *sessionData = NULL;+	uint32_t delete_session = 0;++	/* The SID passed in should be our driver ID. We can return the     */+	/* local ID (LID) which is a unique identifier which we can use     */+	/* to differentiate between the encrypt/decrypt LAC session handles */+	if (NULL == sid) {+		EPRINTK("%s(): Invalid input parameters - NULL sid.\n",+			__FUNCTION__);+		return EINVAL;+	}++	if (NULL == cri) {+		EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",+			__FUNCTION__);+		return EINVAL;+	}++	if (icp_ocfDrvDriverId != *sid) {+		EPRINTK("%s(): Invalid input parameters - bad driver ID\n",+			__FUNCTION__);+		EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);+		return EINVAL;+	}++	sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);+	if (NULL == sessionData) {+		DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);+		return ENOMEM;+	}++	/*ENTER CRITICAL SECTION */+	icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);+	/*put this check in the spinlock so no new sessions can be added to the+	   linked list when we are exiting */+	if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {+		delete_session++;++	} else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {+		if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=+		    (max_sessions -+		     icp_atomic_read(&lac_session_failed_dereg_count))) {+			delete_session++;+		} else {+			icp_atomic_inc(&num_ocf_to_drv_registered_sessions);+			/* Add to session data linked list */+			ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,+				     listNode);+		}++	} else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {+		ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,+			     listNode);+	}++	sessionData->inUse = ICP_SESSION_INITIALISED;++	/*EXIT CRITICAL SECTION */+	icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);++	if (delete_session) {+		DPRINTK("%s():No Session handles available\n", __FUNCTION__);+		ICP_CACHE_FREE(drvSessionData_zone, sessionData);+		return EPERM;+	}++	if (ICP_OCF_DRV_STATUS_SUCCESS !=+	    icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {+		DPRINTK("%s():algorithm not supported\n", __FUNCTION__);+		icp_ocfDrvFreeOCFSession(sessionData);+		return EINVAL;+	}++	if (cri->cri_next) {+		if (cri->cri_next->cri_next != NULL) {+			DPRINTK("%s():only two chained algorithms supported\n",+				__FUNCTION__);+			icp_ocfDrvFreeOCFSession(sessionData);+			return EPERM;+		}++		if (ICP_OCF_DRV_STATUS_SUCCESS !=+		    icp_ocfDrvAlgorithmSetup(cri->cri_next,+					     &(sessionData->lacSessCtx))) {+			DPRINTK("%s():second algorithm not supported\n",+				__FUNCTION__);+			icp_ocfDrvFreeOCFSession(sessionData);+			return EINVAL;+		}++		sessionData->lacSessCtx.symOperation =+		    CPA_CY_SYM_OP_ALGORITHM_CHAINING;+	}++	*sid = (uint32_t) sessionData;++	return ICP_OCF_DRV_STATUS_SUCCESS;+}++/* Name        : icp_ocfDrvAlgorithmSetup+ *+ * Description : This function builds the session context data from the+ * information supplied through OCF. Algorithm chain order and whether the+ * session is Encrypt/Decrypt can only be found out at perform time however, so+ * the session is registered with LAC at that time.+ */+static int+icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,+			 CpaCySymSessionSetupData * lacSessCtx)+{++	lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;++	switch (cri->cri_alg) {++	case CRYPTO_NULL_CBC:+		DPRINTK("%s(): NULL CBC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;+		lacSessCtx->cipherSetupData.cipherAlgorithm =+		    CPA_CY_SYM_CIPHER_NULL;+		lacSessCtx->cipherSetupData.cipherKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;+		break;++	case CRYPTO_DES_CBC:+		DPRINTK("%s(): DES CBC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;+		lacSessCtx->cipherSetupData.cipherAlgorithm =+		    CPA_CY_SYM_CIPHER_DES_CBC;+		lacSessCtx->cipherSetupData.cipherKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;+		break;++	case CRYPTO_3DES_CBC:+		DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;+		lacSessCtx->cipherSetupData.cipherAlgorithm =+		    CPA_CY_SYM_CIPHER_3DES_CBC;+		lacSessCtx->cipherSetupData.cipherKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;+		break;++	case CRYPTO_AES_CBC:+		DPRINTK("%s(): AES CBC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;+		lacSessCtx->cipherSetupData.cipherAlgorithm =+		    CPA_CY_SYM_CIPHER_AES_CBC;+		lacSessCtx->cipherSetupData.cipherKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;+		break;++	case CRYPTO_ARC4:+		DPRINTK("%s(): ARC4\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;+		lacSessCtx->cipherSetupData.cipherAlgorithm =+		    CPA_CY_SYM_CIPHER_ARC4;+		lacSessCtx->cipherSetupData.cipherKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;+		break;++	case CRYPTO_SHA1:+		DPRINTK("%s(): SHA1\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);++		break;++	case CRYPTO_SHA1_HMAC:+		DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);+		lacSessCtx->hashSetupData.authModeSetupData.authKey =+		    cri->cri_key;+		lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;++		break;++	case CRYPTO_SHA2_256:+		DPRINTK("%s(): SHA256\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm =+		    CPA_CY_SYM_HASH_SHA256;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);++		break;++	case CRYPTO_SHA2_256_HMAC:+		DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm =+		    CPA_CY_SYM_HASH_SHA256;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);+		lacSessCtx->hashSetupData.authModeSetupData.authKey =+		    cri->cri_key;+		lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;++		break;++	case CRYPTO_SHA2_384:+		DPRINTK("%s(): SHA384\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm =+		    CPA_CY_SYM_HASH_SHA384;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);++		break;++	case CRYPTO_SHA2_384_HMAC:+		DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm =+		    CPA_CY_SYM_HASH_SHA384;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);+		lacSessCtx->hashSetupData.authModeSetupData.authKey =+		    cri->cri_key;+		lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;++		break;++	case CRYPTO_SHA2_512:+		DPRINTK("%s(): SHA512\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm =+		    CPA_CY_SYM_HASH_SHA512;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);++		break;++	case CRYPTO_SHA2_512_HMAC:+		DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm =+		    CPA_CY_SYM_HASH_SHA512;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);+		lacSessCtx->hashSetupData.authModeSetupData.authKey =+		    cri->cri_key;+		lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;++		break;++	case CRYPTO_MD5:+		DPRINTK("%s(): MD5\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);++		break;++	case CRYPTO_MD5_HMAC:+		DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);+		lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;+		lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;+		lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;+		lacSessCtx->hashSetupData.digestResultLenInBytes =+		    (cri->cri_mlen ?+		     cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);+		lacSessCtx->hashSetupData.authModeSetupData.authKey =+		    cri->cri_key;+		lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =+		    cri->cri_klen / NUM_BITS_IN_BYTE;+		lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;++		break;++	default:+		DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);+		return ICP_OCF_DRV_STATUS_FAIL;+	}++	return ICP_OCF_DRV_STATUS_SUCCESS;+}++/* Name        : icp_ocfDrvFreeOCFSession+ *+ * Description : This function deletes all existing Session data representing+ * the Cryptographic session established between OCF and this driver. This+ * also includes freeing the memory allocated for the session context. The+ * session object is also removed from the session linked list.+ */+static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)+{++	sessionData->inUse = ICP_SESSION_DEREGISTERED;++	/*ENTER CRITICAL SECTION */+	icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);++	if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {+		/*If the Driver is exiting, allow that process to+		   handle any deletions */+		/*EXIT CRITICAL SECTION */+		icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);+		return;+	}++	icp_atomic_dec(&num_ocf_to_drv_registered_sessions);++	ICP_LIST_DEL(sessionData, listNode);++	/*EXIT CRITICAL SECTION */+	icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);++	if (NULL != sessionData->sessHandle) {+		icp_kfree(sessionData->sessHandle);+	}+	ICP_CACHE_FREE(drvSessionData_zone, sessionData);+}++/* Name        : icp_ocfDrvFreeLACSession+ *+ * Description : This attempts to deregister a LAC session. If it fails, the+ * deregistation retry function is called.+ */+int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)+{+	CpaCySymSessionCtx sessionToDeregister = NULL;+	struct icp_drvSessionData *sessionData = NULL;+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	int retval = 0;++	sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);+	if (NULL == sessionData) {+		EPRINTK("%s(): OCF Free session called with Null Session ID.\n",+			__FUNCTION__);+		return EINVAL;+	}++	sessionToDeregister = sessionData->sessHandle;++	if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&+	    (ICP_SESSION_RUNNING != sessionData->inUse) &&+	    (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {+		DPRINTK("%s() Session not initialised.\n", __FUNCTION__);+		return EINVAL;+	}++	if (ICP_SESSION_RUNNING == sessionData->inUse) {+		lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,+						  sessionToDeregister);+		if (CPA_STATUS_RETRY == lacStatus) {+			if (ICP_OCF_DRV_STATUS_SUCCESS !=+			    icp_ocfDrvDeregRetry(&sessionToDeregister)) {+				/* the retry function increments the +				   dereg failed count */+				DPRINTK("%s(): LAC failed to deregister the "+					"session. (localSessionId= %p)\n",+					__FUNCTION__, sessionToDeregister);+				retval = EPERM;+			}++		} else if (CPA_STATUS_SUCCESS != lacStatus) {+			DPRINTK("%s(): LAC failed to deregister the session. "+				"localSessionId= %p, lacStatus = %d\n",+				__FUNCTION__, sessionToDeregister, lacStatus);+			icp_atomic_inc(&lac_session_failed_dereg_count);+			retval = EPERM;+		}+	} else {+		DPRINTK("%s() Session not registered with LAC.\n",+			__FUNCTION__);+	}++	icp_ocfDrvFreeOCFSession(sessionData);+	return retval;++}++/* Name        : icp_ocfDrvAlgCheck + *+ * Description : This function checks whether the cryptodesc argument pertains+ * to a sym or hash function+ */+static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)+{++	if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||+	    crp_desc->crd_alg == CRYPTO_AES_CBC ||+	    crp_desc->crd_alg == CRYPTO_DES_CBC ||+	    crp_desc->crd_alg == CRYPTO_NULL_CBC ||+	    crp_desc->crd_alg == CRYPTO_ARC4) {+		return ICP_OCF_DRV_ALG_CIPHER;+	}++	return ICP_OCF_DRV_ALG_HASH;+}++/* Name        : icp_ocfDrvSymProcess + *+ * Description : This function will map symmetric functionality calls from OCF+ * to the LAC API. It will also allocate memory to store the session context.+ * + * Notes: If it is the first perform call for a given session, then a LAC+ * session is registered. After the session is registered, no checks as+ * to whether session paramaters have changed (e.g. alg chain order) are+ * done.+ */+int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)+{+	struct icp_drvSessionData *sessionData = NULL;+	struct icp_drvOpData *drvOpData = NULL;+	CpaStatus lacStatus = CPA_STATUS_SUCCESS;+	Cpa32U sessionCtxSizeInBytes = 0;++	if (NULL == crp) {+		DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",+			__FUNCTION__);+		return EINVAL;+	}++	if (NULL == crp->crp_desc) {+		DPRINTK("%s(): Invalid input parameters, no crp_desc attached "+			"to crp\n", __FUNCTION__);+		crp->crp_etype = EINVAL;+		return EINVAL;+	}++	if (NULL == crp->crp_buf) {+		DPRINTK("%s(): Invalid input parameters, no buffer attached "+			"to crp\n", __FUNCTION__);+		crp->crp_etype = EINVAL;+		return EINVAL;+	}++	if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {+		crp->crp_etype = EFAULT;+		return EFAULT;+	}++	sessionData = (struct icp_drvSessionData *)+	    (CRYPTO_SESID2LID(crp->crp_sid));+	if (NULL == sessionData) {+		DPRINTK("%s(): Invalid input parameters, Null Session ID \n",+			__FUNCTION__);+		crp->crp_etype = EINVAL;+		return EINVAL;+	}++/*If we get a request against a deregisted session, cancel operation*/+	if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {+		DPRINTK("%s(): Session ID %d was deregistered \n",+			__FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));+		crp->crp_etype = EFAULT;+		return EFAULT;+	}++/*If none of the session states are set, then the session structure was either+  not initialised properly or we are reading from a freed memory area (possible+  due to OCF batch mode not removing queued requests against deregistered +  sessions*/+	if (ICP_SESSION_INITIALISED != sessionData->inUse &&+	    ICP_SESSION_RUNNING != sessionData->inUse) {+		DPRINTK("%s(): Session - ID %d - not properly initialised or "+			"memory freed back to the kernel \n",+			__FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));+		crp->crp_etype = EINVAL;+		return EINVAL;+	}++	/*For the below checks, remember error checking is already done in LAC.+	   We're not validating inputs subsequent to registration */+	if (sessionData->inUse == ICP_SESSION_INITIALISED) {+		DPRINTK("%s(): Initialising session\n", __FUNCTION__);++		if (NULL != crp->crp_desc->crd_next) {+			if (ICP_OCF_DRV_ALG_CIPHER ==+			    icp_ocfDrvAlgCheck(crp->crp_desc)) {++				sessionData->lacSessCtx.algChainOrder =+				    CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;++				if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {+					sessionData->lacSessCtx.cipherSetupData.+					    cipherDirection =+					    CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;+				} else {+					sessionData->lacSessCtx.cipherSetupData.+					    cipherDirection =+					    CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;+				}+			} else {+				sessionData->lacSessCtx.algChainOrder =+				    CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;++				if (crp->crp_desc->crd_next->crd_flags &+				    CRD_F_ENCRYPT) {+					sessionData->lacSessCtx.cipherSetupData.+					    cipherDirection =+					    CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;+				} else {+					sessionData->lacSessCtx.cipherSetupData.+					    cipherDirection =+					    CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;+				}++			}++		} else if (ICP_OCF_DRV_ALG_CIPHER ==+			   icp_ocfDrvAlgCheck(crp->crp_desc)) {+			if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {+				sessionData->lacSessCtx.cipherSetupData.+				    cipherDirection =+				    CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;+			} else {+				sessionData->lacSessCtx.cipherSetupData.+				    cipherDirection =+				    CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;+			}++		}++		/*No action required for standalone Auth here */++		/* Allocate memory for SymSessionCtx before the Session Registration */+		lacStatus =+		    cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,+					      &(sessionData->lacSessCtx),+					      &sessionCtxSizeInBytes);+		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",+				__FUNCTION__, lacStatus);+			crp->crp_etype = EINVAL;+			return EINVAL;+		}+		sessionData->sessHandle =+		    icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);+		if (NULL == sessionData->sessHandle) {+			EPRINTK+			    ("%s(): Failed to get memory for SymSessionCtx\n",+			     __FUNCTION__);+			crp->crp_etype = ENOMEM;+			return ENOMEM;+		}++		lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,+						icp_ocfDrvSymCallBack,+						&(sessionData->lacSessCtx),+						sessionData->sessHandle);++		if (CPA_STATUS_SUCCESS != lacStatus) {+			EPRINTK("%s(): cpaCySymInitSession failed -%d \n",+				__FUNCTION__, lacStatus);+			crp->crp_etype = EFAULT;+			return EFAULT;+		}++		sessionData->inUse = ICP_SESSION_RUNNING;+	}++	drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);+	if (NULL == drvOpData) {+		EPRINTK("%s():Failed to get memory for drvOpData\n",+			__FUNCTION__);+		crp->crp_etype = ENOMEM;+		return ENOMEM;+	}++	drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;+	drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.+	    digestResultLenInBytes;+	drvOpData->crp = crp;++	/* Set the default buffer list array memory allocation */+	drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;+	drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;++	if (ICP_OCF_DRV_STATUS_SUCCESS !=+	    icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {+		crp->crp_etype = EINVAL;+		goto err;+	}++	if (drvOpData->crp->crp_desc->crd_next != NULL) {+		if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->+					       crp_desc->crd_next)) {+			crp->crp_etype = EINVAL;+			goto err;+		}++	}++	/* +	 * Allocate buffer list array memory if the data fragment is more than+	 * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not +	 * calculated already+	 */+	if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {+		if (NULL == drvOpData->lacOpData.pDigestResult) {+			drvOpData->numBufferListArray =+			    icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)+							 crp->crp_buf);+		}++		if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <+		    drvOpData->numBufferListArray) {+			DPRINTK("%s() numBufferListArray more than default\n",+				__FUNCTION__);+			drvOpData->srcBuffer.pBuffers = NULL;+			drvOpData->srcBuffer.pBuffers =+			    icp_kmalloc(drvOpData->numBufferListArray *+					sizeof(CpaFlatBuffer), ICP_M_NOWAIT);+			if (NULL == drvOpData->srcBuffer.pBuffers) {+				EPRINTK("%s() Failed to get memory for "+					"pBuffers\n", __FUNCTION__);+				ICP_CACHE_FREE(drvOpData_zone, drvOpData);+				crp->crp_etype = ENOMEM;+				return ENOMEM;+			}+		}+	}++	/*+	 * Check the type of buffer structure we got and convert it into+	 * CpaBufferList format.+	 */+	if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {+		if (ICP_OCF_DRV_STATUS_SUCCESS !=+		    icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)+						     crp->crp_buf,+						     &(drvOpData->srcBuffer))) {+			EPRINTK("%s():Failed to translate from packet buffer "+				"to bufferlist\n", __FUNCTION__);+			crp->crp_etype = EINVAL;+			goto err;+		}++		drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		/* OCF only supports IOV of one entry. */+		if (NUM_IOV_SUPPORTED ==+		    ((struct uio *)(crp->crp_buf))->uio_iovcnt) {++			icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->+									crp_buf))->+							uio_iov[0].iov_base,+							((struct uio *)(crp->+									crp_buf))->+							uio_iov[0].iov_len,+							&(drvOpData->+							  srcBuffer));++			drvOpData->bufferType = CRYPTO_F_IOV;++		} else {+			DPRINTK("%s():Unable to handle IOVs with lengths of "+				"greater than one!\n", __FUNCTION__);+			crp->crp_etype = EINVAL;+			goto err;+		}++	} else {+		icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,+						crp->crp_ilen,+						&(drvOpData->srcBuffer));++		drvOpData->bufferType = CRYPTO_BUF_CONTIG;+	}++	/* Allocate srcBuffer's private meta data */+	if (ICP_OCF_DRV_STATUS_SUCCESS !=+	    icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {+		EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);+		memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));+		crp->crp_etype = EINVAL;+		goto err;+	}++	/* Perform "in-place" crypto operation */+	lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,+				      (void *)drvOpData,+				      &(drvOpData->lacOpData),+				      &(drvOpData->srcBuffer),+				      &(drvOpData->srcBuffer),+				      &(drvOpData->verifyResult));+	if (CPA_STATUS_RETRY == lacStatus) {+		DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",+			__FUNCTION__, lacStatus);+		memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));+		crp->crp_etype = ERESTART;+		goto err;+	}+	if (CPA_STATUS_SUCCESS != lacStatus) {+		EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",+			__FUNCTION__, lacStatus);+		memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));+		crp->crp_etype = EINVAL;+		goto err;+	}++	return 0;		//OCF success status value++      err:+	if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {+		icp_kfree(drvOpData->srcBuffer.pBuffers);+	}+	icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));+	ICP_CACHE_FREE(drvOpData_zone, drvOpData);++	return crp->crp_etype;+}++/* Name        : icp_ocfDrvProcessDataSetup+ *+ * Description : This function will setup all the cryptographic operation data+ *               that is required by LAC to execute the operation.+ */+static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,+				      struct cryptodesc *crp_desc)+{+	CpaCyRandGenOpData randGenOpData;+	CpaFlatBuffer randData;++	drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;++	/* Convert from the cryptop to the ICP LAC crypto parameters */+	switch (crp_desc->crd_alg) {+	case CRYPTO_NULL_CBC:+		drvOpData->lacOpData.+		    cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;+		drvOpData->lacOpData.+		    messageLenToCipherInBytes = crp_desc->crd_len;+		drvOpData->verifyResult = CPA_FALSE;+		drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;+		break;+	case CRYPTO_DES_CBC:+		drvOpData->lacOpData.+		    cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;+		drvOpData->lacOpData.+		    messageLenToCipherInBytes = crp_desc->crd_len;+		drvOpData->verifyResult = CPA_FALSE;+		drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;+		break;+	case CRYPTO_3DES_CBC:+		drvOpData->lacOpData.+		    cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;+		drvOpData->lacOpData.+		    messageLenToCipherInBytes = crp_desc->crd_len;+		drvOpData->verifyResult = CPA_FALSE;+		drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;+		break;+	case CRYPTO_ARC4:+		drvOpData->lacOpData.+		    cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;+		drvOpData->lacOpData.+		    messageLenToCipherInBytes = crp_desc->crd_len;+		drvOpData->verifyResult = CPA_FALSE;+		drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;+		break;+	case CRYPTO_AES_CBC:+		drvOpData->lacOpData.+		    cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;+		drvOpData->lacOpData.+		    messageLenToCipherInBytes = crp_desc->crd_len;+		drvOpData->verifyResult = CPA_FALSE;+		drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;+		break;+	case CRYPTO_SHA1:+	case CRYPTO_SHA1_HMAC:+	case CRYPTO_SHA2_256:+	case CRYPTO_SHA2_256_HMAC:+	case CRYPTO_SHA2_384:+	case CRYPTO_SHA2_384_HMAC:+	case CRYPTO_SHA2_512:+	case CRYPTO_SHA2_512_HMAC:+	case CRYPTO_MD5:+	case CRYPTO_MD5_HMAC:+		drvOpData->lacOpData.+		    hashStartSrcOffsetInBytes = crp_desc->crd_skip;+		drvOpData->lacOpData.+		    messageLenToHashInBytes = crp_desc->crd_len;+		drvOpData->lacOpData.+		    pDigestResult =+		    icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);++		if (NULL == drvOpData->lacOpData.pDigestResult) {+			DPRINTK("%s(): ERROR - could not calculate "+				"Digest Result memory address\n", __FUNCTION__);+			return ICP_OCF_DRV_STATUS_FAIL;+		}++		drvOpData->lacOpData.digestVerify = CPA_FALSE;+		break;+	default:+		DPRINTK("%s(): Crypto process error - algorithm not "+			"found \n", __FUNCTION__);+		return ICP_OCF_DRV_STATUS_FAIL;+	}++	/* Figure out what the IV is supposed to be */+	if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||+	    (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||+	    (crp_desc->crd_alg == CRYPTO_AES_CBC)) {+		/*ARC4 doesn't use an IV */+		if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {+			/* Explicit IV provided to OCF */+			drvOpData->lacOpData.pIv = crp_desc->crd_iv;+		} else {+			/* IV is not explicitly provided to OCF */++			/* Point the LAC OP Data IV pointer to our allocated+			   storage location for this session. */+			drvOpData->lacOpData.pIv = drvOpData->ivData;++			if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&+			    ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {++				/* Encrypting - need to create IV */+				randGenOpData.generateBits = CPA_TRUE;+				randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;++				icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)+								drvOpData->+								ivData,+								MAX_IV_LEN_IN_BYTES,+								&randData);++				if (CPA_STATUS_SUCCESS !=+				    cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,+						 NULL, NULL,+						 &randGenOpData, &randData)) {+					DPRINTK("%s(): ERROR - Failed to"+						" generate"+						" Initialisation Vector\n",+						__FUNCTION__);+					return ICP_OCF_DRV_STATUS_FAIL;+				}++				crypto_copyback(drvOpData->crp->+						crp_flags,+						drvOpData->crp->crp_buf,+						crp_desc->crd_inject,+						drvOpData->lacOpData.+						ivLenInBytes,+						(caddr_t) (drvOpData->lacOpData.+							   pIv));+			} else {+				/* Reading IV from buffer */+				crypto_copydata(drvOpData->crp->+						crp_flags,+						drvOpData->crp->crp_buf,+						crp_desc->crd_inject,+						drvOpData->lacOpData.+						ivLenInBytes,+						(caddr_t) (drvOpData->lacOpData.+							   pIv));+			}++		}++	}++	return ICP_OCF_DRV_STATUS_SUCCESS;+}++/* Name        : icp_ocfDrvDigestPointerFind+ *+ * Description : This function is used to find the memory address of where the+ * digest information shall be stored in. Input buffer types are an skbuff, iov+ * or flat buffer. The address is found using the buffer data start address and+ * an offset.+ *+ * Note: In the case of a linux skbuff, the digest address may exist within+ * a memory space linked to from the start buffer. These linked memory spaces+ * must be traversed by the data length offset in order to find the digest start+ * address. Whether there is enough space for the digest must also be checked.+ */+uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,+				     struct cryptodesc * crp_desc)+{++	int offsetInBytes = crp_desc->crd_inject;+	uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;+	uint8_t *flat_buffer_base = NULL;+	int flat_buffer_length = 0;++	if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {++		return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,+							       offsetInBytes,+							       digestSizeInBytes);++	} else {+		/* IOV or flat buffer */+		if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {+			/*single IOV check has already been done */+			flat_buffer_base = ((struct uio *)+					    (drvOpData->crp->crp_buf))->+			    uio_iov[0].iov_base;+			flat_buffer_length = ((struct uio *)+					      (drvOpData->crp->crp_buf))->+			    uio_iov[0].iov_len;+		} else {+			flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;+			flat_buffer_length = drvOpData->crp->crp_ilen;+		}++		if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {+			DPRINTK("%s() Not enough space for Digest "+				"(IOV/Flat Buffer) \n", __FUNCTION__);+			return NULL;+		} else {+			return (uint8_t *) (flat_buffer_base + offsetInBytes);+		}+	}+	DPRINTK("%s() Should not reach this point\n", __FUNCTION__);+	return NULL;+}diff -Nur linux-2.6.36.orig/crypto/ocf/ep80579/Makefile linux-2.6.36/crypto/ocf/ep80579/Makefile--- linux-2.6.36.orig/crypto/ocf/ep80579/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ep80579/Makefile	2010-11-09 20:28:04.742495461 +0100@@ -0,0 +1,119 @@+#########################################################################+#+#  Targets supported+#  all     - builds everything and installs+#  install - identical to all+#  depend  - build dependencies+#  clean   - clears derived objects except the .depend files+#  distclean- clears all derived objects and the .depend file+#  +# @par+# This file is provided under a dual BSD/GPLv2 license.  When using or +#   redistributing this file, you may do so under either license.+# +#   GPL LICENSE SUMMARY+# +#   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+# +#   This program is free software; you can redistribute it and/or modify +#   it under the terms of version 2 of the GNU General Public License as+#   published by the Free Software Foundation.+# +#   This program is distributed in the hope that it will be useful, but +#   WITHOUT ANY WARRANTY; without even the implied warranty of +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +#   General Public License for more details.+# +#   You should have received a copy of the GNU General Public License +#   along with this program; if not, write to the Free Software +#   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.+#   The full GNU General Public License is included in this distribution +#   in the file called LICENSE.GPL.+# +#   Contact Information:+#   Intel Corporation+# +#   BSD LICENSE +# +#   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.+#   All rights reserved.+# +#   Redistribution and use in source and binary forms, with or without +#   modification, are permitted provided that the following conditions +#   are met:+# +#     * Redistributions of source code must retain the above copyright +#       notice, this list of conditions and the following disclaimer.+#     * Redistributions in binary form must reproduce the above copyright +#       notice, this list of conditions and the following disclaimer in +#       the documentation and/or other materials provided with the +#       distribution.+#     * Neither the name of Intel Corporation nor the names of its +#       contributors may be used to endorse or promote products derived +#       from this software without specific prior written permission.+# +#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+# +# +#  version: Security.L.1.0.2-229+############################################################################+++####################Common variables and definitions########################++ifndef ICP_ROOT+$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \+        "-> setenv ICP_ROOT <path>")+all fastdep:+	:+else++ifndef KERNEL_SOURCE_ROOT+$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \+        "-> setenv KERNEL_SOURCE_ROOT <path>")+endif++# Ensure The ENV_DIR environmental var is defined.+ifndef ICP_ENV_DIR+$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \+        "-> setenv ICP_ENV_DIR <path>")+endif++#Add your project environment Makefile+include ${ICP_ENV_DIR}/environment.mk++#include the makefile with all the default and common Make variable definitions+include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk++#Add the name for the executable, Library or Module output definitions+OUTPUT_NAME= icp_ocf++# List of Source Files to be compiled +SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c++#common includes between all supported OSes+INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \+-I${ICP_OCF_SRC_DIR}++# The location of the os level makefile needs to be changed.+include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk++# On the line directly below list the outputs you wish to build for,+# e.g "lib_static lib_shared exe module" as shown below+install: module++###################Include rules makefiles########################+include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk+###################End of Rules inclusion#########################++endifdiff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.36/crypto/ocf/hifn/hifn7751.c--- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/hifn7751.c	2010-11-09 20:28:04.752495537 +0100@@ -0,0 +1,2976 @@+/*	$OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $	*/++/*-+ * Invertex AEON / Hifn 7751 driver+ * Copyright (c) 1999 Invertex Inc. All rights reserved.+ * Copyright (c) 1999 Theo de Raadt+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.+ *			http://www.netsec.net+ * Copyright (c) 2003 Hifn Inc.+ *+ * This driver is based on a previous driver by Invertex, for which they+ * requested:  Please send any comments, feedback, bug-fixes, or feature+ * requests to software@invertex.com.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+ *+__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");+ */++/*+ * Driver for various Hifn encryption processors.+ */+#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/wait.h>+#include <linux/sched.h>+#include <linux/pci.h>+#include <linux/delay.h>+#include <linux/interrupt.h>+#include <linux/spinlock.h>+#include <linux/random.h>+#include <linux/version.h>+#include <linux/skbuff.h>+#include <asm/io.h>++#include <cryptodev.h>+#include <uio.h>+#include <hifn/hifn7751reg.h>+#include <hifn/hifn7751var.h>++#if 1+#define	DPRINTF(a...)	if (hifn_debug) { \+							printk("%s: ", sc ? \+								device_get_nameunit(sc->sc_dev) : "hifn"); \+							printk(a); \+						} else+#else+#define	DPRINTF(a...)+#endif++static inline int+pci_get_revid(struct pci_dev *dev)+{+	u8 rid = 0;+	pci_read_config_byte(dev, PCI_REVISION_ID, &rid);+	return rid;+}++static	struct hifn_stats hifnstats;++#define	debug hifn_debug+int hifn_debug = 0;+module_param(hifn_debug, int, 0644);+MODULE_PARM_DESC(hifn_debug, "Enable debug");++int hifn_maxbatch = 1;+module_param(hifn_maxbatch, int, 0644);+MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");++int hifn_cache_linesize = 0x10;+module_param(hifn_cache_linesize, int, 0444);+MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");++#ifdef MODULE_PARM+char *hifn_pllconfig = NULL;+MODULE_PARM(hifn_pllconfig, "s");+#else+char hifn_pllconfig[32]; /* This setting is RO after loading */+module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);+#endif+MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");++#ifdef HIFN_VULCANDEV+#include <sys/conf.h>+#include <sys/uio.h>++static struct cdevsw vulcanpk_cdevsw; /* forward declaration */+#endif++/*+ * Prototypes and count for the pci_device structure+ */+static	int  hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);+static	void hifn_remove(struct pci_dev *dev);++static	int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);+static	int hifn_freesession(device_t, u_int64_t);+static	int hifn_process(device_t, struct cryptop *, int);++static device_method_t hifn_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	hifn_newsession),+	DEVMETHOD(cryptodev_freesession,hifn_freesession),+	DEVMETHOD(cryptodev_process,	hifn_process),+};++static	void hifn_reset_board(struct hifn_softc *, int);+static	void hifn_reset_puc(struct hifn_softc *);+static	void hifn_puc_wait(struct hifn_softc *);+static	int hifn_enable_crypto(struct hifn_softc *);+static	void hifn_set_retry(struct hifn_softc *sc);+static	void hifn_init_dma(struct hifn_softc *);+static	void hifn_init_pci_registers(struct hifn_softc *);+static	int hifn_sramsize(struct hifn_softc *);+static	int hifn_dramsize(struct hifn_softc *);+static	int hifn_ramtype(struct hifn_softc *);+static	void hifn_sessions(struct hifn_softc *);+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+static irqreturn_t hifn_intr(int irq, void *arg);+#else+static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);+#endif+static	u_int hifn_write_command(struct hifn_command *, u_int8_t *);+static	u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);+static	void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);+static	int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);+static	int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);+static	int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);+static	int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);+static	int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);+static	int hifn_init_pubrng(struct hifn_softc *);+static	void hifn_tick(unsigned long arg);+static	void hifn_abort(struct hifn_softc *);+static	void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);++static	void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);+static	void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);++#ifdef CONFIG_OCF_RANDOMHARVEST+static	int hifn_read_random(void *arg, u_int32_t *buf, int len);+#endif++#define HIFN_MAX_CHIPS	8+static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];++static __inline u_int32_t+READ_REG_0(struct hifn_softc *sc, bus_size_t reg)+{+	u_int32_t v = readl(sc->sc_bar0 + reg);+	sc->sc_bar0_lastreg = (bus_size_t) -1;+	return (v);+}+#define	WRITE_REG_0(sc, reg, val)	hifn_write_reg_0(sc, reg, val)++static __inline u_int32_t+READ_REG_1(struct hifn_softc *sc, bus_size_t reg)+{+	u_int32_t v = readl(sc->sc_bar1 + reg);+	sc->sc_bar1_lastreg = (bus_size_t) -1;+	return (v);+}+#define	WRITE_REG_1(sc, reg, val)	hifn_write_reg_1(sc, reg, val)++/*+ * map in a given buffer (great on some arches :-)+ */++static int+pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)+{+	struct iovec *iov = uio->uio_iov;++	DPRINTF("%s()\n", __FUNCTION__);++	buf->mapsize = 0;+	for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {+		buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,+				iov->iov_base, iov->iov_len,+				PCI_DMA_BIDIRECTIONAL);+		buf->segs[buf->nsegs].ds_len = iov->iov_len;+		buf->mapsize += iov->iov_len;+		iov++;+		buf->nsegs++;+	}+	/* identify this buffer by the first segment */+	buf->map = (void *) buf->segs[0].ds_addr;+	return(0);+}++/*+ * map in a given sk_buff+ */++static int+pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)+{+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	buf->mapsize = 0;++	buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,+			skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);+	buf->segs[0].ds_len = skb_headlen(skb);+	buf->mapsize += buf->segs[0].ds_len;++	buf->nsegs = 1;++	for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {+		buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;+		buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,+				page_address(skb_shinfo(skb)->frags[i].page) ++					skb_shinfo(skb)->frags[i].page_offset,+				buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);+		buf->mapsize += buf->segs[buf->nsegs].ds_len;+		buf->nsegs++;+	}++	/* identify this buffer by the first segment */+	buf->map = (void *) buf->segs[0].ds_addr;+	return(0);+}++/*+ * map in a given contiguous buffer+ */++static int+pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)+{+	DPRINTF("%s()\n", __FUNCTION__);++	buf->mapsize = 0;+	buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,+			b, len, PCI_DMA_BIDIRECTIONAL);+	buf->segs[0].ds_len = len;+	buf->mapsize += buf->segs[0].ds_len;+	buf->nsegs = 1;++	/* identify this buffer by the first segment */+	buf->map = (void *) buf->segs[0].ds_addr;+	return(0);+}++#if 0 /* not needed at this time */+static void+pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)+{+	int i;++	DPRINTF("%s()\n", __FUNCTION__);+	for (i = 0; i < buf->nsegs; i++)+		pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,+				buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);+}+#endif++static void+pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)+{+	int i;+	DPRINTF("%s()\n", __FUNCTION__);+	for (i = 0; i < buf->nsegs; i++) {+		pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,+				buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);+		buf->segs[i].ds_addr = 0;+		buf->segs[i].ds_len = 0;+	}+	buf->nsegs = 0;+	buf->mapsize = 0;+	buf->map = 0;+}++static const char*+hifn_partname(struct hifn_softc *sc)+{+	/* XXX sprintf numbers when not decoded */+	switch (pci_get_vendor(sc->sc_pcidev)) {+	case PCI_VENDOR_HIFN:+		switch (pci_get_device(sc->sc_pcidev)) {+		case PCI_PRODUCT_HIFN_6500:	return "Hifn 6500";+		case PCI_PRODUCT_HIFN_7751:	return "Hifn 7751";+		case PCI_PRODUCT_HIFN_7811:	return "Hifn 7811";+		case PCI_PRODUCT_HIFN_7951:	return "Hifn 7951";+		case PCI_PRODUCT_HIFN_7955:	return "Hifn 7955";+		case PCI_PRODUCT_HIFN_7956:	return "Hifn 7956";+		}+		return "Hifn unknown-part";+	case PCI_VENDOR_INVERTEX:+		switch (pci_get_device(sc->sc_pcidev)) {+		case PCI_PRODUCT_INVERTEX_AEON:	return "Invertex AEON";+		}+		return "Invertex unknown-part";+	case PCI_VENDOR_NETSEC:+		switch (pci_get_device(sc->sc_pcidev)) {+		case PCI_PRODUCT_NETSEC_7751:	return "NetSec 7751";+		}+		return "NetSec unknown-part";+	}+	return "Unknown-vendor unknown-part";+}++static u_int+checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)+{+	struct hifn_softc *sc = pci_get_drvdata(dev);+	if (v > max) {+		device_printf(sc->sc_dev, "Warning, %s %u out of range, "+			"using max %u\n", what, v, max);+		v = max;+	} else if (v < min) {+		device_printf(sc->sc_dev, "Warning, %s %u out of range, "+			"using min %u\n", what, v, min);+		v = min;+	}+	return v;+}++/*+ * Select PLL configuration for 795x parts.  This is complicated in+ * that we cannot determine the optimal parameters without user input.+ * The reference clock is derived from an external clock through a+ * multiplier.  The external clock is either the host bus (i.e. PCI)+ * or an external clock generator.  When using the PCI bus we assume+ * the clock is either 33 or 66 MHz; for an external source we cannot+ * tell the speed.+ *+ * PLL configuration is done with a string: "pci" for PCI bus, or "ext"+ * for an external source, followed by the frequency.  We calculate+ * the appropriate multiplier and PLL register contents accordingly.+ * When no configuration is given we default to "pci66" since that+ * always will allow the card to work.  If a card is using the PCI+ * bus clock and in a 33MHz slot then it will be operating at half+ * speed until the correct information is provided.+ *+ * We use a default setting of "ext66" because according to Mike Ham+ * of HiFn, almost every board in existence has an external crystal+ * populated at 66Mhz. Using PCI can be a problem on modern motherboards,+ * because PCI33 can have clocks from 0 to 33Mhz, and some have+ * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.+ */+static void+hifn_getpllconfig(struct pci_dev *dev, u_int *pll)+{+	const char *pllspec = hifn_pllconfig;+	u_int freq, mul, fl, fh;+	u_int32_t pllconfig;+	char *nxt;++	if (pllspec == NULL)+		pllspec = "ext66";+	fl = 33, fh = 66;+	pllconfig = 0;+	if (strncmp(pllspec, "ext", 3) == 0) {+		pllspec += 3;+		pllconfig |= HIFN_PLL_REF_SEL;+		switch (pci_get_device(dev)) {+		case PCI_PRODUCT_HIFN_7955:+		case PCI_PRODUCT_HIFN_7956:+			fl = 20, fh = 100;+			break;+#ifdef notyet+		case PCI_PRODUCT_HIFN_7954:+			fl = 20, fh = 66;+			break;+#endif+		}+	} else if (strncmp(pllspec, "pci", 3) == 0)+		pllspec += 3;+	freq = strtoul(pllspec, &nxt, 10);+	if (nxt == pllspec)+		freq = 66;+	else+		freq = checkmaxmin(dev, "frequency", freq, fl, fh);+	/*+	 * Calculate multiplier.  We target a Fck of 266 MHz,+	 * allowing only even values, possibly rounded down.+	 * Multipliers > 8 must set the charge pump current.+	 */+	mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);+	pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;+	if (mul > 8)+		pllconfig |= HIFN_PLL_IS;+	*pll = pllconfig;+}++/*+ * Attach an interface that successfully probed.+ */+static int+hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)+{+	struct hifn_softc *sc = NULL;+	char rbase;+	u_int16_t ena, rev;+	int rseg, rc;+	unsigned long mem_start, mem_len;+	static int num_chips = 0;++	DPRINTF("%s()\n", __FUNCTION__);++	if (pci_enable_device(dev) < 0)+		return(-ENODEV);++	if (pci_set_mwi(dev))+		return(-ENODEV);++	if (!dev->irq) {+		printk("hifn: found device with no IRQ assigned. check BIOS settings!");+		pci_disable_device(dev);+		return(-ENODEV);+	}++	sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);+	if (!sc)+		return(-ENOMEM);+	memset(sc, 0, sizeof(*sc));++	softc_device_init(sc, "hifn", num_chips, hifn_methods);++	sc->sc_pcidev = dev;+	sc->sc_irq = -1;+	sc->sc_cid = -1;+	sc->sc_num = num_chips++;+	if (sc->sc_num < HIFN_MAX_CHIPS)+		hifn_chip_idx[sc->sc_num] = sc;++	pci_set_drvdata(sc->sc_pcidev, sc);++	spin_lock_init(&sc->sc_mtx);++	/* XXX handle power management */++	/*+	 * The 7951 and 795x have a random number generator and+	 * public key support; note this.+	 */+	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&+	    (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))+		sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;+	/*+	 * The 7811 has a random number generator and+	 * we also note it's identity 'cuz of some quirks.+	 */+	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&+	    pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)+		sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;++	/*+	 * The 795x parts support AES.+	 */+	if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&+	    (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||+	     pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {+		sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;+		/*+		 * Select PLL configuration.  This depends on the+		 * bus and board design and must be manually configured+		 * if the default setting is unacceptable.+		 */+		hifn_getpllconfig(dev, &sc->sc_pllconfig);+	}++	/*+	 * Setup PCI resources. Note that we record the bus+	 * tag and handle for each register mapping, this is+	 * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,+	 * and WRITE_REG_1 macros throughout the driver.+	 */+	mem_start = pci_resource_start(sc->sc_pcidev, 0);+	mem_len   = pci_resource_len(sc->sc_pcidev, 0);+	sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);+	if (!sc->sc_bar0) {+		device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);+		goto fail;+	}+	sc->sc_bar0_lastreg = (bus_size_t) -1;++	mem_start = pci_resource_start(sc->sc_pcidev, 1);+	mem_len   = pci_resource_len(sc->sc_pcidev, 1);+	sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);+	if (!sc->sc_bar1) {+		device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);+		goto fail;+	}+	sc->sc_bar1_lastreg = (bus_size_t) -1;++	/* fix up the bus size */+	if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {+		device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");+		goto fail;+	}+	if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {+		device_printf(sc->sc_dev,+				"No usable consistent DMA configuration, aborting.\n");+		goto fail;+	}++	hifn_set_retry(sc);++	/*+	 * Setup the area where the Hifn DMA's descriptors+	 * and associated data structures.+	 */+	sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,+			sizeof(*sc->sc_dma),+			&sc->sc_dma_physaddr);+	if (!sc->sc_dma) {+		device_printf(sc->sc_dev, "cannot alloc sc_dma\n");+		goto fail;+	}+	bzero(sc->sc_dma, sizeof(*sc->sc_dma));++	/*+	 * Reset the board and do the ``secret handshake''+	 * to enable the crypto support.  Then complete the+	 * initialization procedure by setting up the interrupt+	 * and hooking in to the system crypto support so we'll+	 * get used for system services like the crypto device,+	 * IPsec, RNG device, etc.+	 */+	hifn_reset_board(sc, 0);++	if (hifn_enable_crypto(sc) != 0) {+		device_printf(sc->sc_dev, "crypto enabling failed\n");+		goto fail;+	}+	hifn_reset_puc(sc);++	hifn_init_dma(sc);+	hifn_init_pci_registers(sc);++	pci_set_master(sc->sc_pcidev);++	/* XXX can't dynamically determine ram type for 795x; force dram */+	if (sc->sc_flags & HIFN_IS_7956)+		sc->sc_drammodel = 1;+	else if (hifn_ramtype(sc))+		goto fail;++	if (sc->sc_drammodel == 0)+		hifn_sramsize(sc);+	else+		hifn_dramsize(sc);++	/*+	 * Workaround for NetSec 7751 rev A: half ram size because two+	 * of the address lines were left floating+	 */+	if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&+	    pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&+	    pci_get_revid(dev) == 0x61)	/*XXX???*/+		sc->sc_ramsize >>= 1;++	/*+	 * Arrange the interrupt line.+	 */+	rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);+	if (rc) {+		device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);+		goto fail;+	}+	sc->sc_irq = dev->irq;++	hifn_sessions(sc);++	/*+	 * NB: Keep only the low 16 bits; this masks the chip id+	 *     from the 7951.+	 */+	rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;++	rseg = sc->sc_ramsize / 1024;+	rbase = 'K';+	if (sc->sc_ramsize >= (1024 * 1024)) {+		rbase = 'M';+		rseg /= 1024;+	}+	device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",+		hifn_partname(sc), rev,+		rseg, rbase, sc->sc_drammodel ? 'd' : 's');+	if (sc->sc_flags & HIFN_IS_7956)+		printf(", pll=0x%x<%s clk, %ux mult>",+			sc->sc_pllconfig,+			sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",+			2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));+	printf("\n");++	sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);+	if (sc->sc_cid < 0) {+		device_printf(sc->sc_dev, "could not get crypto driver id\n");+		goto fail;+	}++	WRITE_REG_0(sc, HIFN_0_PUCNFG,+	    READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);+	ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;++	switch (ena) {+	case HIFN_PUSTAT_ENA_2:+		crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);+		if (sc->sc_flags & HIFN_HAS_AES)+			crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);+		/*FALLTHROUGH*/+	case HIFN_PUSTAT_ENA_1:+		crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);+		break;+	}++	if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))+		hifn_init_pubrng(sc);++	init_timer(&sc->sc_tickto);+	sc->sc_tickto.function = hifn_tick;+	sc->sc_tickto.data = (unsigned long) sc->sc_num;+	mod_timer(&sc->sc_tickto, jiffies + HZ);++	return (0);++fail:+    if (sc->sc_cid >= 0)+        crypto_unregister_all(sc->sc_cid);+    if (sc->sc_irq != -1)+        free_irq(sc->sc_irq, sc);+    if (sc->sc_dma) {+		/* Turn off DMA polling */+		WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+			HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);++        pci_free_consistent(sc->sc_pcidev,+				sizeof(*sc->sc_dma),+                sc->sc_dma, sc->sc_dma_physaddr);+	}+    kfree(sc);+	return (-ENXIO);+}++/*+ * Detach an interface that successfully probed.+ */+static void+hifn_remove(struct pci_dev *dev)+{+	struct hifn_softc *sc = pci_get_drvdata(dev);+	unsigned long l_flags;++	DPRINTF("%s()\n", __FUNCTION__);++	KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));++	/* disable interrupts */+	HIFN_LOCK(sc);+	WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);+	HIFN_UNLOCK(sc);++	/*XXX other resources */+	del_timer_sync(&sc->sc_tickto);++	/* Turn off DMA polling */+	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+	    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);++	crypto_unregister_all(sc->sc_cid);++	free_irq(sc->sc_irq, sc);++	pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),+                sc->sc_dma, sc->sc_dma_physaddr);+}+++static int+hifn_init_pubrng(struct hifn_softc *sc)+{+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	if ((sc->sc_flags & HIFN_IS_7811) == 0) {+		/* Reset 7951 public key/rng engine */+		WRITE_REG_1(sc, HIFN_1_PUB_RESET,+		    READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);++		for (i = 0; i < 100; i++) {+			DELAY(1000);+			if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &+			    HIFN_PUBRST_RESET) == 0)+				break;+		}++		if (i == 100) {+			device_printf(sc->sc_dev, "public key init failed\n");+			return (1);+		}+	}++	/* Enable the rng, if available */+#ifdef CONFIG_OCF_RANDOMHARVEST+	if (sc->sc_flags & HIFN_HAS_RNG) {+		if (sc->sc_flags & HIFN_IS_7811) {+			u_int32_t r;+			r = READ_REG_1(sc, HIFN_1_7811_RNGENA);+			if (r & HIFN_7811_RNGENA_ENA) {+				r &= ~HIFN_7811_RNGENA_ENA;+				WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);+			}+			WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,+			    HIFN_7811_RNGCFG_DEFL);+			r |= HIFN_7811_RNGENA_ENA;+			WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);+		} else+			WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,+			    READ_REG_1(sc, HIFN_1_RNG_CONFIG) |+			    HIFN_RNGCFG_ENA);++		sc->sc_rngfirst = 1;+		crypto_rregister(sc->sc_cid, hifn_read_random, sc);+	}+#endif++	/* Enable public key engine, if available */+	if (sc->sc_flags & HIFN_HAS_PUBLIC) {+		WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);+		sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;+		WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);+#ifdef HIFN_VULCANDEV+		sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0, +					UID_ROOT, GID_WHEEL, 0666,+					"vulcanpk");+		sc->sc_pkdev->si_drv1 = sc;+#endif+	}++	return (0);+}++#ifdef CONFIG_OCF_RANDOMHARVEST+static int+hifn_read_random(void *arg, u_int32_t *buf, int len)+{+	struct hifn_softc *sc = (struct hifn_softc *) arg;+	u_int32_t sts;+	int i, rc = 0;++	if (len <= 0)+		return rc;++	if (sc->sc_flags & HIFN_IS_7811) {+		/* ONLY VALID ON 7811!!!! */+		for (i = 0; i < 5; i++) {+			sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);+			if (sts & HIFN_7811_RNGSTS_UFL) {+				device_printf(sc->sc_dev,+					      "RNG underflow: disabling\n");+				/* DAVIDM perhaps return -1 */+				break;+			}+			if ((sts & HIFN_7811_RNGSTS_RDY) == 0)+				break;++			/*+			 * There are at least two words in the RNG FIFO+			 * at this point.+			 */+			if (rc < len)+				buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);+			if (rc < len)+				buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);+		}+	} else+		buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);++	/* NB: discard first data read */+	if (sc->sc_rngfirst) {+		sc->sc_rngfirst = 0;+		rc = 0;+	}++	return(rc);+}+#endif /* CONFIG_OCF_RANDOMHARVEST */++static void+hifn_puc_wait(struct hifn_softc *sc)+{+	int i;+	int reg = HIFN_0_PUCTRL;++	if (sc->sc_flags & HIFN_IS_7956) {+		reg = HIFN_0_PUCTRL2;+	}++	for (i = 5000; i > 0; i--) {+		DELAY(1);+		if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))+			break;+	}+	if (!i)+		device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",+				READ_REG_0(sc, HIFN_0_PUCTRL));+}++/*+ * Reset the processing unit.+ */+static void+hifn_reset_puc(struct hifn_softc *sc)+{+	/* Reset processing unit */+	int reg = HIFN_0_PUCTRL;++	if (sc->sc_flags & HIFN_IS_7956) {+		reg = HIFN_0_PUCTRL2;+	}+	WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);++	hifn_puc_wait(sc);+}++/*+ * Set the Retry and TRDY registers; note that we set them to+ * zero because the 7811 locks up when forced to retry (section+ * 3.6 of "Specification Update SU-0014-04".  Not clear if we+ * should do this for all Hifn parts, but it doesn't seem to hurt.+ */+static void+hifn_set_retry(struct hifn_softc *sc)+{+	DPRINTF("%s()\n", __FUNCTION__);+	/* NB: RETRY only responds to 8-bit reads/writes */+	pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);+	pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);+	/* piggy back the cache line setting here */+	pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);+}++/*+ * Resets the board.  Values in the regesters are left as is+ * from the reset (i.e. initial values are assigned elsewhere).+ */+static void+hifn_reset_board(struct hifn_softc *sc, int full)+{+	u_int32_t reg;++	DPRINTF("%s()\n", __FUNCTION__);+	/*+	 * Set polling in the DMA configuration register to zero.  0x7 avoids+	 * resetting the board and zeros out the other fields.+	 */+	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+	    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);++	/*+	 * Now that polling has been disabled, we have to wait 1 ms+	 * before resetting the board.+	 */+	DELAY(1000);++	/* Reset the DMA unit */+	if (full) {+		WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);+		DELAY(1000);+	} else {+		WRITE_REG_1(sc, HIFN_1_DMA_CNFG,+		    HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);+		hifn_reset_puc(sc);+	}++	KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));+	bzero(sc->sc_dma, sizeof(*sc->sc_dma));++	/* Bring dma unit out of reset */+	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+	    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);++	hifn_puc_wait(sc);+	hifn_set_retry(sc);++	if (sc->sc_flags & HIFN_IS_7811) {+		for (reg = 0; reg < 1000; reg++) {+			if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &+			    HIFN_MIPSRST_CRAMINIT)+				break;+			DELAY(1000);+		}+		if (reg == 1000)+			device_printf(sc->sc_dev, ": cram init timeout\n");+	} else {+	  /* set up DMA configuration register #2 */+	  /* turn off all PK and BAR0 swaps */+	  WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,+		      (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|+		      (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|+		      (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|+		      (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));+	}+}++static u_int32_t+hifn_next_signature(u_int32_t a, u_int cnt)+{+	int i;+	u_int32_t v;++	for (i = 0; i < cnt; i++) {++		/* get the parity */+		v = a & 0x80080125;+		v ^= v >> 16;+		v ^= v >> 8;+		v ^= v >> 4;+		v ^= v >> 2;+		v ^= v >> 1;++		a = (v & 1) ^ (a << 1);+	}++	return a;+}+++/*+ * Checks to see if crypto is already enabled.  If crypto isn't enable,+ * "hifn_enable_crypto" is called to enable it.  The check is important,+ * as enabling crypto twice will lock the board.+ */+static int +hifn_enable_crypto(struct hifn_softc *sc)+{+	u_int32_t dmacfg, ramcfg, encl, addr, i;+	char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+					  0x00, 0x00, 0x00, 0x00 };++	DPRINTF("%s()\n", __FUNCTION__);++	ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);+	dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);++	/*+	 * The RAM config register's encrypt level bit needs to be set before+	 * every read performed on the encryption level register.+	 */+	WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);++	encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;++	/*+	 * Make sure we don't re-unlock.  Two unlocks kills chip until the+	 * next reboot.+	 */+	if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {+#ifdef HIFN_DEBUG+		if (hifn_debug)+			device_printf(sc->sc_dev,+			    "Strong crypto already enabled!\n");+#endif+		goto report;+	}++	if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {+#ifdef HIFN_DEBUG+		if (hifn_debug)+			device_printf(sc->sc_dev,+			      "Unknown encryption level 0x%x\n", encl);+#endif+		return 1;+	}++	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |+	    HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);+	DELAY(1000);+	addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);+	DELAY(1000);+	WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);+	DELAY(1000);++	for (i = 0; i <= 12; i++) {+		addr = hifn_next_signature(addr, offtbl[i] + 0x101);+		WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);++		DELAY(1000);+	}++	WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);+	encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;++#ifdef HIFN_DEBUG+	if (hifn_debug) {+		if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)+			device_printf(sc->sc_dev, "Engine is permanently "+				"locked until next system reset!\n");+		else+			device_printf(sc->sc_dev, "Engine enabled "+				"successfully!\n");+	}+#endif++report:+	WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);+	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);++	switch (encl) {+	case HIFN_PUSTAT_ENA_1:+	case HIFN_PUSTAT_ENA_2:+		break;+	case HIFN_PUSTAT_ENA_0:+	default:+		device_printf(sc->sc_dev, "disabled\n");+		break;+	}++	return 0;+}++/*+ * Give initial values to the registers listed in the "Register Space"+ * section of the HIFN Software Development reference manual.+ */+static void +hifn_init_pci_registers(struct hifn_softc *sc)+{+	DPRINTF("%s()\n", __FUNCTION__);++	/* write fixed values needed by the Initialization registers */+	WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);+	WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);+	WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);++	/* write all 4 ring address registers */+	WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr ++	    offsetof(struct hifn_dma, cmdr[0]));+	WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr ++	    offsetof(struct hifn_dma, srcr[0]));+	WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr ++	    offsetof(struct hifn_dma, dstr[0]));+	WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr ++	    offsetof(struct hifn_dma, resr[0]));++	DELAY(2000);++	/* write status register */+	WRITE_REG_1(sc, HIFN_1_DMA_CSR,+	    HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |+	    HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |+	    HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |+	    HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |+	    HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |+	    HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |+	    HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |+	    HIFN_DMACSR_S_WAIT |+	    HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |+	    HIFN_DMACSR_C_WAIT |+	    HIFN_DMACSR_ENGINE |+	    ((sc->sc_flags & HIFN_HAS_PUBLIC) ?+		HIFN_DMACSR_PUBDONE : 0) |+	    ((sc->sc_flags & HIFN_IS_7811) ?+		HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));++	sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;+	sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |+	    HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |+	    HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |+	    ((sc->sc_flags & HIFN_IS_7811) ?+		HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);+	sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;+	WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);+++	if (sc->sc_flags & HIFN_IS_7956) {+		u_int32_t pll;++		WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |+		    HIFN_PUCNFG_TCALLPHASES |+		    HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);++		/* turn off the clocks and insure bypass is set */+		pll = READ_REG_1(sc, HIFN_1_PLL);+		pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))+		  | HIFN_PLL_BP | HIFN_PLL_MBSET;+		WRITE_REG_1(sc, HIFN_1_PLL, pll);+		DELAY(10*1000);		/* 10ms */++		/* change configuration */+		pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;+		WRITE_REG_1(sc, HIFN_1_PLL, pll);+		DELAY(10*1000);		/* 10ms */++		/* disable bypass */+		pll &= ~HIFN_PLL_BP;+		WRITE_REG_1(sc, HIFN_1_PLL, pll);+		/* enable clocks with new configuration */+		pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;+		WRITE_REG_1(sc, HIFN_1_PLL, pll);+	} else {+		WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |+		    HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |+		    HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |+		    (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));+	}++	WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);+	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+	    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |+	    ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |+	    ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));+}++/*+ * The maximum number of sessions supported by the card+ * is dependent on the amount of context ram, which+ * encryption algorithms are enabled, and how compression+ * is configured.  This should be configured before this+ * routine is called.+ */+static void+hifn_sessions(struct hifn_softc *sc)+{+	u_int32_t pucnfg;+	int ctxsize;++	DPRINTF("%s()\n", __FUNCTION__);++	pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);++	if (pucnfg & HIFN_PUCNFG_COMPSING) {+		if (pucnfg & HIFN_PUCNFG_ENCCNFG)+			ctxsize = 128;+		else+			ctxsize = 512;+		/*+		 * 7955/7956 has internal context memory of 32K+		 */+		if (sc->sc_flags & HIFN_IS_7956)+			sc->sc_maxses = 32768 / ctxsize;+		else+			sc->sc_maxses = 1 ++			    ((sc->sc_ramsize - 32768) / ctxsize);+	} else+		sc->sc_maxses = sc->sc_ramsize / 16384;++	if (sc->sc_maxses > 2048)+		sc->sc_maxses = 2048;+}++/*+ * Determine ram type (sram or dram).  Board should be just out of a reset+ * state when this is called.+ */+static int+hifn_ramtype(struct hifn_softc *sc)+{+	u_int8_t data[8], dataexpect[8];+	int i;++	for (i = 0; i < sizeof(data); i++)+		data[i] = dataexpect[i] = 0x55;+	if (hifn_writeramaddr(sc, 0, data))+		return (-1);+	if (hifn_readramaddr(sc, 0, data))+		return (-1);+	if (bcmp(data, dataexpect, sizeof(data)) != 0) {+		sc->sc_drammodel = 1;+		return (0);+	}++	for (i = 0; i < sizeof(data); i++)+		data[i] = dataexpect[i] = 0xaa;+	if (hifn_writeramaddr(sc, 0, data))+		return (-1);+	if (hifn_readramaddr(sc, 0, data))+		return (-1);+	if (bcmp(data, dataexpect, sizeof(data)) != 0) {+		sc->sc_drammodel = 1;+		return (0);+	}++	return (0);+}++#define	HIFN_SRAM_MAX		(32 << 20)+#define	HIFN_SRAM_STEP_SIZE	16384+#define	HIFN_SRAM_GRANULARITY	(HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)++static int+hifn_sramsize(struct hifn_softc *sc)+{+	u_int32_t a;+	u_int8_t data[8];+	u_int8_t dataexpect[sizeof(data)];+	int32_t i;++	for (i = 0; i < sizeof(data); i++)+		data[i] = dataexpect[i] = i ^ 0x5a;++	for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {+		a = i * HIFN_SRAM_STEP_SIZE;+		bcopy(&i, data, sizeof(i));+		hifn_writeramaddr(sc, a, data);+	}++	for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {+		a = i * HIFN_SRAM_STEP_SIZE;+		bcopy(&i, dataexpect, sizeof(i));+		if (hifn_readramaddr(sc, a, data) < 0)+			return (0);+		if (bcmp(data, dataexpect, sizeof(data)) != 0)+			return (0);+		sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;+	}++	return (0);+}++/*+ * XXX For dram boards, one should really try all of the+ * HIFN_PUCNFG_DSZ_*'s.  This just assumes that PUCNFG+ * is already set up correctly.+ */+static int+hifn_dramsize(struct hifn_softc *sc)+{+	u_int32_t cnfg;++	if (sc->sc_flags & HIFN_IS_7956) {+		/*+		 * 7955/7956 have a fixed internal ram of only 32K.+		 */+		sc->sc_ramsize = 32768;+	} else {+		cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &+		    HIFN_PUCNFG_DRAMMASK;+		sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);+	}+	return (0);+}++static void+hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)+{+	struct hifn_dma *dma = sc->sc_dma;++	DPRINTF("%s()\n", __FUNCTION__);++	if (dma->cmdi == HIFN_D_CMD_RSIZE) {+		dma->cmdi = 0;+		dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);+		wmb();+		dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);+		HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+	}+	*cmdp = dma->cmdi++;+	dma->cmdk = dma->cmdi;++	if (dma->srci == HIFN_D_SRC_RSIZE) {+		dma->srci = 0;+		dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);+		wmb();+		dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);+		HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+	}+	*srcp = dma->srci++;+	dma->srck = dma->srci;++	if (dma->dsti == HIFN_D_DST_RSIZE) {+		dma->dsti = 0;+		dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);+		wmb();+		dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);+		HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+	}+	*dstp = dma->dsti++;+	dma->dstk = dma->dsti;++	if (dma->resi == HIFN_D_RES_RSIZE) {+		dma->resi = 0;+		dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);+		wmb();+		dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);+		HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+	}+	*resp = dma->resi++;+	dma->resk = dma->resi;+}++static int+hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)+{+	struct hifn_dma *dma = sc->sc_dma;+	hifn_base_command_t wc;+	const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;+	int r, cmdi, resi, srci, dsti;++	DPRINTF("%s()\n", __FUNCTION__);++	wc.masks = htole16(3 << 13);+	wc.session_num = htole16(addr >> 14);+	wc.total_source_count = htole16(8);+	wc.total_dest_count = htole16(addr & 0x3fff);++	hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);++	WRITE_REG_1(sc, HIFN_1_DMA_CSR,+	    HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |+	    HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);++	/* build write command */+	bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);+	*(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;+	bcopy(data, &dma->test_src, sizeof(dma->test_src));++	dma->srcr[srci].p = htole32(sc->sc_dma_physaddr+	    + offsetof(struct hifn_dma, test_src));+	dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr+	    + offsetof(struct hifn_dma, test_dst));++	dma->cmdr[cmdi].l = htole32(16 | masks);+	dma->srcr[srci].l = htole32(8 | masks);+	dma->dstr[dsti].l = htole32(4 | masks);+	dma->resr[resi].l = htole32(4 | masks);++	for (r = 10000; r >= 0; r--) {+		DELAY(10);+		if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)+			break;+	}+	if (r == 0) {+		device_printf(sc->sc_dev, "writeramaddr -- "+		    "result[%d](addr %d) still valid\n", resi, addr);+		r = -1;+		return (-1);+	} else+		r = 0;++	WRITE_REG_1(sc, HIFN_1_DMA_CSR,+	    HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |+	    HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);++	return (r);+}++static int+hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)+{+	struct hifn_dma *dma = sc->sc_dma;+	hifn_base_command_t rc;+	const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;+	int r, cmdi, srci, dsti, resi;++	DPRINTF("%s()\n", __FUNCTION__);++	rc.masks = htole16(2 << 13);+	rc.session_num = htole16(addr >> 14);+	rc.total_source_count = htole16(addr & 0x3fff);+	rc.total_dest_count = htole16(8);++	hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);++	WRITE_REG_1(sc, HIFN_1_DMA_CSR,+	    HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |+	    HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);++	bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);+	*(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;++	dma->srcr[srci].p = htole32(sc->sc_dma_physaddr ++	    offsetof(struct hifn_dma, test_src));+	dma->test_src = 0;+	dma->dstr[dsti].p =  htole32(sc->sc_dma_physaddr ++	    offsetof(struct hifn_dma, test_dst));+	dma->test_dst = 0;+	dma->cmdr[cmdi].l = htole32(8 | masks);+	dma->srcr[srci].l = htole32(8 | masks);+	dma->dstr[dsti].l = htole32(8 | masks);+	dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);++	for (r = 10000; r >= 0; r--) {+		DELAY(10);+		if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)+			break;+	}+	if (r == 0) {+		device_printf(sc->sc_dev, "readramaddr -- "+		    "result[%d](addr %d) still valid\n", resi, addr);+		r = -1;+	} else {+		r = 0;+		bcopy(&dma->test_dst, data, sizeof(dma->test_dst));+	}++	WRITE_REG_1(sc, HIFN_1_DMA_CSR,+	    HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |+	    HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);++	return (r);+}++/*+ * Initialize the descriptor rings.+ */+static void +hifn_init_dma(struct hifn_softc *sc)+{+	struct hifn_dma *dma = sc->sc_dma;+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	hifn_set_retry(sc);++	/* initialize static pointer values */+	for (i = 0; i < HIFN_D_CMD_RSIZE; i++)+		dma->cmdr[i].p = htole32(sc->sc_dma_physaddr ++		    offsetof(struct hifn_dma, command_bufs[i][0]));+	for (i = 0; i < HIFN_D_RES_RSIZE; i++)+		dma->resr[i].p = htole32(sc->sc_dma_physaddr ++		    offsetof(struct hifn_dma, result_bufs[i][0]));++	dma->cmdr[HIFN_D_CMD_RSIZE].p =+	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));+	dma->srcr[HIFN_D_SRC_RSIZE].p =+	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));+	dma->dstr[HIFN_D_DST_RSIZE].p =+	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));+	dma->resr[HIFN_D_RES_RSIZE].p =+	    htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));++	dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;+	dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;+	dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;+}++/*+ * Writes out the raw command buffer space.  Returns the+ * command buffer size.+ */+static u_int+hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)+{+	struct hifn_softc *sc = NULL;+	u_int8_t *buf_pos;+	hifn_base_command_t *base_cmd;+	hifn_mac_command_t *mac_cmd;+	hifn_crypt_command_t *cry_cmd;+	int using_mac, using_crypt, len, ivlen;+	u_int32_t dlen, slen;++	DPRINTF("%s()\n", __FUNCTION__);++	buf_pos = buf;+	using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;+	using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;++	base_cmd = (hifn_base_command_t *)buf_pos;+	base_cmd->masks = htole16(cmd->base_masks);+	slen = cmd->src_mapsize;+	if (cmd->sloplen)+		dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);+	else+		dlen = cmd->dst_mapsize;+	base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);+	base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);+	dlen >>= 16;+	slen >>= 16;+	base_cmd->session_num = htole16(+	    ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |+	    ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));+	buf_pos += sizeof(hifn_base_command_t);++	if (using_mac) {+		mac_cmd = (hifn_mac_command_t *)buf_pos;+		dlen = cmd->maccrd->crd_len;+		mac_cmd->source_count = htole16(dlen & 0xffff);+		dlen >>= 16;+		mac_cmd->masks = htole16(cmd->mac_masks |+		    ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));+		mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);+		mac_cmd->reserved = 0;+		buf_pos += sizeof(hifn_mac_command_t);+	}++	if (using_crypt) {+		cry_cmd = (hifn_crypt_command_t *)buf_pos;+		dlen = cmd->enccrd->crd_len;+		cry_cmd->source_count = htole16(dlen & 0xffff);+		dlen >>= 16;+		cry_cmd->masks = htole16(cmd->cry_masks |+		    ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));+		cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);+		cry_cmd->reserved = 0;+		buf_pos += sizeof(hifn_crypt_command_t);+	}++	if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {+		bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);+		buf_pos += HIFN_MAC_KEY_LENGTH;+	}++	if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {+		switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {+		case HIFN_CRYPT_CMD_ALG_3DES:+			bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);+			buf_pos += HIFN_3DES_KEY_LENGTH;+			break;+		case HIFN_CRYPT_CMD_ALG_DES:+			bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);+			buf_pos += HIFN_DES_KEY_LENGTH;+			break;+		case HIFN_CRYPT_CMD_ALG_RC4:+			len = 256;+			do {+				int clen;++				clen = MIN(cmd->cklen, len);+				bcopy(cmd->ck, buf_pos, clen);+				len -= clen;+				buf_pos += clen;+			} while (len > 0);+			bzero(buf_pos, 4);+			buf_pos += 4;+			break;+		case HIFN_CRYPT_CMD_ALG_AES:+			/*+			 * AES keys are variable 128, 192 and+			 * 256 bits (16, 24 and 32 bytes).+			 */+			bcopy(cmd->ck, buf_pos, cmd->cklen);+			buf_pos += cmd->cklen;+			break;+		}+	}++	if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {+		switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {+		case HIFN_CRYPT_CMD_ALG_AES:+			ivlen = HIFN_AES_IV_LENGTH;+			break;+		default:+			ivlen = HIFN_IV_LENGTH;+			break;+		}+		bcopy(cmd->iv, buf_pos, ivlen);+		buf_pos += ivlen;+	}++	if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {+		bzero(buf_pos, 8);+		buf_pos += 8;+	}++	return (buf_pos - buf);+}++static int+hifn_dmamap_aligned(struct hifn_operand *op)+{+	struct hifn_softc *sc = NULL;+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	for (i = 0; i < op->nsegs; i++) {+		if (op->segs[i].ds_addr & 3)+			return (0);+		if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))+			return (0);+	}+	return (1);+}++static __inline int+hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)+{+	struct hifn_dma *dma = sc->sc_dma;++	if (++idx == HIFN_D_DST_RSIZE) {+		dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |+		    HIFN_D_MASKDONEIRQ);+		HIFN_DSTR_SYNC(sc, idx,+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+		idx = 0;+	}+	return (idx);+}++static int+hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)+{+	struct hifn_dma *dma = sc->sc_dma;+	struct hifn_operand *dst = &cmd->dst;+	u_int32_t p, l;+	int idx, used = 0, i;++	DPRINTF("%s()\n", __FUNCTION__);++	idx = dma->dsti;+	for (i = 0; i < dst->nsegs - 1; i++) {+		dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);+		dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);+		wmb();+		dma->dstr[idx].l |= htole32(HIFN_D_VALID);+		HIFN_DSTR_SYNC(sc, idx,+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+		used++;++		idx = hifn_dmamap_dstwrap(sc, idx);+	}++	if (cmd->sloplen == 0) {+		p = dst->segs[i].ds_addr;+		l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |+		    dst->segs[i].ds_len;+	} else {+		p = sc->sc_dma_physaddr ++		    offsetof(struct hifn_dma, slop[cmd->slopidx]);+		l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |+		    sizeof(u_int32_t);++		if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {+			dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);+			dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |+			    (dst->segs[i].ds_len - cmd->sloplen));+			wmb();+			dma->dstr[idx].l |= htole32(HIFN_D_VALID);+			HIFN_DSTR_SYNC(sc, idx,+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+			used++;++			idx = hifn_dmamap_dstwrap(sc, idx);+		}+	}+	dma->dstr[idx].p = htole32(p);+	dma->dstr[idx].l = htole32(l);+	wmb();+	dma->dstr[idx].l |= htole32(HIFN_D_VALID);+	HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+	used++;++	idx = hifn_dmamap_dstwrap(sc, idx);++	dma->dsti = idx;+	dma->dstu += used;+	return (idx);+}++static __inline int+hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)+{+	struct hifn_dma *dma = sc->sc_dma;++	if (++idx == HIFN_D_SRC_RSIZE) {+		dma->srcr[idx].l = htole32(HIFN_D_VALID |+		    HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);+		HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+		idx = 0;+	}+	return (idx);+}++static int+hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)+{+	struct hifn_dma *dma = sc->sc_dma;+	struct hifn_operand *src = &cmd->src;+	int idx, i;+	u_int32_t last = 0;++	DPRINTF("%s()\n", __FUNCTION__);++	idx = dma->srci;+	for (i = 0; i < src->nsegs; i++) {+		if (i == src->nsegs - 1)+			last = HIFN_D_LAST;++		dma->srcr[idx].p = htole32(src->segs[i].ds_addr);+		dma->srcr[idx].l = htole32(src->segs[i].ds_len |+		    HIFN_D_MASKDONEIRQ | last);+		wmb();+		dma->srcr[idx].l |= htole32(HIFN_D_VALID);+		HIFN_SRCR_SYNC(sc, idx,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);++		idx = hifn_dmamap_srcwrap(sc, idx);+	}+	dma->srci = idx;+	dma->srcu += src->nsegs;+	return (idx);+} +++static int +hifn_crypto(+	struct hifn_softc *sc,+	struct hifn_command *cmd,+	struct cryptop *crp,+	int hint)+{+	struct	hifn_dma *dma = sc->sc_dma;+	u_int32_t cmdlen, csr;+	int cmdi, resi, err = 0;+	unsigned long l_flags;++	DPRINTF("%s()\n", __FUNCTION__);++	/*+	 * need 1 cmd, and 1 res+	 *+	 * NB: check this first since it's easy.+	 */+	HIFN_LOCK(sc);+	if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||+	    (dma->resu + 1) > HIFN_D_RES_RSIZE) {+#ifdef HIFN_DEBUG+		if (hifn_debug) {+			device_printf(sc->sc_dev,+				"cmd/result exhaustion, cmdu %u resu %u\n",+				dma->cmdu, dma->resu);+		}+#endif+		hifnstats.hst_nomem_cr++;+		sc->sc_needwakeup |= CRYPTO_SYMQ;+		HIFN_UNLOCK(sc);+		return (ERESTART);+	}++	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {+			hifnstats.hst_nomem_load++;+			err = ENOMEM;+			goto err_srcmap1;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {+			hifnstats.hst_nomem_load++;+			err = ENOMEM;+			goto err_srcmap1;+		}+	} else {+		if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {+			hifnstats.hst_nomem_load++;+			err = ENOMEM;+			goto err_srcmap1;+		}+	}++	if (hifn_dmamap_aligned(&cmd->src)) {+		cmd->sloplen = cmd->src_mapsize & 3;+		cmd->dst = cmd->src;+	} else {+		if (crp->crp_flags & CRYPTO_F_IOV) {+			DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+			err = EINVAL;+			goto err_srcmap;+		} else if (crp->crp_flags & CRYPTO_F_SKBUF) {+#ifdef NOTYET+			int totlen, len;+			struct mbuf *m, *m0, *mlast;++			KASSERT(cmd->dst_m == cmd->src_m,+				("hifn_crypto: dst_m initialized improperly"));+			hifnstats.hst_unaligned++;+			/*+			 * Source is not aligned on a longword boundary.+			 * Copy the data to insure alignment.  If we fail+			 * to allocate mbufs or clusters while doing this+			 * we return ERESTART so the operation is requeued+			 * at the crypto later, but only if there are+			 * ops already posted to the hardware; otherwise we+			 * have no guarantee that we'll be re-entered.+			 */+			totlen = cmd->src_mapsize;+			if (cmd->src_m->m_flags & M_PKTHDR) {+				len = MHLEN;+				MGETHDR(m0, M_DONTWAIT, MT_DATA);+				if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {+					m_free(m0);+					m0 = NULL;+				}+			} else {+				len = MLEN;+				MGET(m0, M_DONTWAIT, MT_DATA);+			}+			if (m0 == NULL) {+				hifnstats.hst_nomem_mbuf++;+				err = dma->cmdu ? ERESTART : ENOMEM;+				goto err_srcmap;+			}+			if (totlen >= MINCLSIZE) {+				MCLGET(m0, M_DONTWAIT);+				if ((m0->m_flags & M_EXT) == 0) {+					hifnstats.hst_nomem_mcl++;+					err = dma->cmdu ? ERESTART : ENOMEM;+					m_freem(m0);+					goto err_srcmap;+				}+				len = MCLBYTES;+			}+			totlen -= len;+			m0->m_pkthdr.len = m0->m_len = len;+			mlast = m0;++			while (totlen > 0) {+				MGET(m, M_DONTWAIT, MT_DATA);+				if (m == NULL) {+					hifnstats.hst_nomem_mbuf++;+					err = dma->cmdu ? ERESTART : ENOMEM;+					m_freem(m0);+					goto err_srcmap;+				}+				len = MLEN;+				if (totlen >= MINCLSIZE) {+					MCLGET(m, M_DONTWAIT);+					if ((m->m_flags & M_EXT) == 0) {+						hifnstats.hst_nomem_mcl++;+						err = dma->cmdu ? ERESTART : ENOMEM;+						mlast->m_next = m;+						m_freem(m0);+						goto err_srcmap;+					}+					len = MCLBYTES;+				}++				m->m_len = len;+				m0->m_pkthdr.len += len;+				totlen -= len;++				mlast->m_next = m;+				mlast = m;+			}+			cmd->dst_m = m0;+#else+			device_printf(sc->sc_dev,+					"%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",+					__FILE__, __LINE__);+			err = EINVAL;+			goto err_srcmap;+#endif+		} else {+			device_printf(sc->sc_dev,+					"%s,%d: unaligned contig buffers not implemented\n",+					__FILE__, __LINE__);+			err = EINVAL;+			goto err_srcmap;+		}+	}++	if (cmd->dst_map == NULL) {+		if (crp->crp_flags & CRYPTO_F_SKBUF) {+			if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {+				hifnstats.hst_nomem_map++;+				err = ENOMEM;+				goto err_dstmap1;+			}+		} else if (crp->crp_flags & CRYPTO_F_IOV) {+			if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {+				hifnstats.hst_nomem_load++;+				err = ENOMEM;+				goto err_dstmap1;+			}+		} else {+			if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {+				hifnstats.hst_nomem_load++;+				err = ENOMEM;+				goto err_dstmap1;+			}+		}+	}++#ifdef HIFN_DEBUG+	if (hifn_debug) {+		device_printf(sc->sc_dev,+		    "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",+		    READ_REG_1(sc, HIFN_1_DMA_CSR),+		    READ_REG_1(sc, HIFN_1_DMA_IER),+		    dma->cmdu, dma->srcu, dma->dstu, dma->resu,+		    cmd->src_nsegs, cmd->dst_nsegs);+	}+#endif++#if 0+	if (cmd->src_map == cmd->dst_map) {+		bus_dmamap_sync(sc->sc_dmat, cmd->src_map,+		    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);+	} else {+		bus_dmamap_sync(sc->sc_dmat, cmd->src_map,+		    BUS_DMASYNC_PREWRITE);+		bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,+		    BUS_DMASYNC_PREREAD);+	}+#endif++	/*+	 * need N src, and N dst+	 */+	if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||+	    (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {+#ifdef HIFN_DEBUG+		if (hifn_debug) {+			device_printf(sc->sc_dev,+				"src/dst exhaustion, srcu %u+%u dstu %u+%u\n",+				dma->srcu, cmd->src_nsegs,+				dma->dstu, cmd->dst_nsegs);+		}+#endif+		hifnstats.hst_nomem_sd++;+		err = ERESTART;+		goto err_dstmap;+	}++	if (dma->cmdi == HIFN_D_CMD_RSIZE) {+		dma->cmdi = 0;+		dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);+		wmb();+		dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);+		HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,+		    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+	}+	cmdi = dma->cmdi++;+	cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);+	HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);++	/* .p for command/result already set */+	dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |+	    HIFN_D_MASKDONEIRQ);+	wmb();+	dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);+	HIFN_CMDR_SYNC(sc, cmdi,+	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);+	dma->cmdu++;++	/*+	 * We don't worry about missing an interrupt (which a "command wait"+	 * interrupt salvages us from), unless there is more than one command+	 * in the queue.+	 */+	if (dma->cmdu > 1) {+		sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;+		WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);+	}++	hifnstats.hst_ipackets++;+	hifnstats.hst_ibytes += cmd->src_mapsize;++	hifn_dmamap_load_src(sc, cmd);++	/*+	 * Unlike other descriptors, we don't mask done interrupt from+	 * result descriptor.+	 */+#ifdef HIFN_DEBUG+	if (hifn_debug)+		device_printf(sc->sc_dev, "load res\n");+#endif+	if (dma->resi == HIFN_D_RES_RSIZE) {+		dma->resi = 0;+		dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);+		wmb();+		dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);+		HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+	}+	resi = dma->resi++;+	KASSERT(dma->hifn_commands[resi] == NULL,+		("hifn_crypto: command slot %u busy", resi));+	dma->hifn_commands[resi] = cmd;+	HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);+	if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {+		dma->resr[resi].l = htole32(HIFN_MAX_RESULT |+		    HIFN_D_LAST | HIFN_D_MASKDONEIRQ);+		wmb();+		dma->resr[resi].l |= htole32(HIFN_D_VALID);+		sc->sc_curbatch++;+		if (sc->sc_curbatch > hifnstats.hst_maxbatch)+			hifnstats.hst_maxbatch = sc->sc_curbatch;+		hifnstats.hst_totbatch++;+	} else {+		dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);+		wmb();+		dma->resr[resi].l |= htole32(HIFN_D_VALID);+		sc->sc_curbatch = 0;+	}+	HIFN_RESR_SYNC(sc, resi,+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+	dma->resu++;++	if (cmd->sloplen)+		cmd->slopidx = resi;++	hifn_dmamap_load_dst(sc, cmd);++	csr = 0;+	if (sc->sc_c_busy == 0) {+		csr |= HIFN_DMACSR_C_CTRL_ENA;+		sc->sc_c_busy = 1;+	}+	if (sc->sc_s_busy == 0) {+		csr |= HIFN_DMACSR_S_CTRL_ENA;+		sc->sc_s_busy = 1;+	}+	if (sc->sc_r_busy == 0) {+		csr |= HIFN_DMACSR_R_CTRL_ENA;+		sc->sc_r_busy = 1;+	}+	if (sc->sc_d_busy == 0) {+		csr |= HIFN_DMACSR_D_CTRL_ENA;+		sc->sc_d_busy = 1;+	}+	if (csr)+		WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);++#ifdef HIFN_DEBUG+	if (hifn_debug) {+		device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",+		    READ_REG_1(sc, HIFN_1_DMA_CSR),+		    READ_REG_1(sc, HIFN_1_DMA_IER));+	}+#endif++	sc->sc_active = 5;+	HIFN_UNLOCK(sc);+	KASSERT(err == 0, ("hifn_crypto: success with error %u", err));+	return (err);		/* success */++err_dstmap:+	if (cmd->src_map != cmd->dst_map)+		pci_unmap_buf(sc, &cmd->dst);+err_dstmap1:+err_srcmap:+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		if (cmd->src_skb != cmd->dst_skb)+#ifdef NOTYET+			m_freem(cmd->dst_m);+#else+			device_printf(sc->sc_dev,+					"%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",+					__FILE__, __LINE__);+#endif+	}+	pci_unmap_buf(sc, &cmd->src);+err_srcmap1:+	HIFN_UNLOCK(sc);+	return (err);+}++static void+hifn_tick(unsigned long arg)+{+	struct hifn_softc *sc;+	unsigned long l_flags;++	if (arg >= HIFN_MAX_CHIPS)+		return;+	sc = hifn_chip_idx[arg];+	if (!sc)+		return;++	HIFN_LOCK(sc);+	if (sc->sc_active == 0) {+		struct hifn_dma *dma = sc->sc_dma;+		u_int32_t r = 0;++		if (dma->cmdu == 0 && sc->sc_c_busy) {+			sc->sc_c_busy = 0;+			r |= HIFN_DMACSR_C_CTRL_DIS;+		}+		if (dma->srcu == 0 && sc->sc_s_busy) {+			sc->sc_s_busy = 0;+			r |= HIFN_DMACSR_S_CTRL_DIS;+		}+		if (dma->dstu == 0 && sc->sc_d_busy) {+			sc->sc_d_busy = 0;+			r |= HIFN_DMACSR_D_CTRL_DIS;+		}+		if (dma->resu == 0 && sc->sc_r_busy) {+			sc->sc_r_busy = 0;+			r |= HIFN_DMACSR_R_CTRL_DIS;+		}+		if (r)+			WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);+	} else+		sc->sc_active--;+	HIFN_UNLOCK(sc);+	mod_timer(&sc->sc_tickto, jiffies + HZ);+}++static irqreturn_t+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+hifn_intr(int irq, void *arg)+#else+hifn_intr(int irq, void *arg, struct pt_regs *regs)+#endif+{+	struct hifn_softc *sc = arg;+	struct hifn_dma *dma;+	u_int32_t dmacsr, restart;+	int i, u;+	unsigned long l_flags;++	dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);++	/* Nothing in the DMA unit interrupted */+	if ((dmacsr & sc->sc_dmaier) == 0)+		return IRQ_NONE;++	HIFN_LOCK(sc);++	dma = sc->sc_dma;++#ifdef HIFN_DEBUG+	if (hifn_debug) {+		device_printf(sc->sc_dev,+		    "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",+		    dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,+		    dma->cmdi, dma->srci, dma->dsti, dma->resi,+		    dma->cmdk, dma->srck, dma->dstk, dma->resk,+		    dma->cmdu, dma->srcu, dma->dstu, dma->resu);+	}+#endif++	WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);++	if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&+	    (dmacsr & HIFN_DMACSR_PUBDONE))+		WRITE_REG_1(sc, HIFN_1_PUB_STATUS,+		    READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);++	restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);+	if (restart)+		device_printf(sc->sc_dev, "overrun %x\n", dmacsr);++	if (sc->sc_flags & HIFN_IS_7811) {+		if (dmacsr & HIFN_DMACSR_ILLR)+			device_printf(sc->sc_dev, "illegal read\n");+		if (dmacsr & HIFN_DMACSR_ILLW)+			device_printf(sc->sc_dev, "illegal write\n");+	}++	restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |+	    HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);+	if (restart) {+		device_printf(sc->sc_dev, "abort, resetting.\n");+		hifnstats.hst_abort++;+		hifn_abort(sc);+		HIFN_UNLOCK(sc);+		return IRQ_HANDLED;+	}++	if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {+		/*+		 * If no slots to process and we receive a "waiting on+		 * command" interrupt, we disable the "waiting on command"+		 * (by clearing it).+		 */+		sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;+		WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);+	}++	/* clear the rings */+	i = dma->resk; u = dma->resu;+	while (u != 0) {+		HIFN_RESR_SYNC(sc, i,+		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);+		if (dma->resr[i].l & htole32(HIFN_D_VALID)) {+			HIFN_RESR_SYNC(sc, i,+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+			break;+		}++		if (i != HIFN_D_RES_RSIZE) {+			struct hifn_command *cmd;+			u_int8_t *macbuf = NULL;++			HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);+			cmd = dma->hifn_commands[i];+			KASSERT(cmd != NULL,+				("hifn_intr: null command slot %u", i));+			dma->hifn_commands[i] = NULL;++			if (cmd->base_masks & HIFN_BASE_CMD_MAC) {+				macbuf = dma->result_bufs[i];+				macbuf += 12;+			}++			hifn_callback(sc, cmd, macbuf);+			hifnstats.hst_opackets++;+			u--;+		}++		if (++i == (HIFN_D_RES_RSIZE + 1))+			i = 0;+	}+	dma->resk = i; dma->resu = u;++	i = dma->srck; u = dma->srcu;+	while (u != 0) {+		if (i == HIFN_D_SRC_RSIZE)+			i = 0;+		HIFN_SRCR_SYNC(sc, i,+		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);+		if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {+			HIFN_SRCR_SYNC(sc, i,+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+			break;+		}+		i++, u--;+	}+	dma->srck = i; dma->srcu = u;++	i = dma->cmdk; u = dma->cmdu;+	while (u != 0) {+		HIFN_CMDR_SYNC(sc, i,+		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);+		if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {+			HIFN_CMDR_SYNC(sc, i,+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+			break;+		}+		if (i != HIFN_D_CMD_RSIZE) {+			u--;+			HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);+		}+		if (++i == (HIFN_D_CMD_RSIZE + 1))+			i = 0;+	}+	dma->cmdk = i; dma->cmdu = u;++	HIFN_UNLOCK(sc);++	if (sc->sc_needwakeup) {		/* XXX check high watermark */+		int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);+#ifdef HIFN_DEBUG+		if (hifn_debug)+			device_printf(sc->sc_dev,+				"wakeup crypto (%x) u %d/%d/%d/%d\n",+				sc->sc_needwakeup,+				dma->cmdu, dma->srcu, dma->dstu, dma->resu);+#endif+		sc->sc_needwakeup &= ~wakeup;+		crypto_unblock(sc->sc_cid, wakeup);+	}++	return IRQ_HANDLED;+}++/*+ * Allocate a new 'session' and return an encoded session id.  'sidp'+ * contains our registration id, and should contain an encoded session+ * id on successful allocation.+ */+static int+hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)+{+	struct hifn_softc *sc = device_get_softc(dev);+	struct cryptoini *c;+	int mac = 0, cry = 0, sesn;+	struct hifn_session *ses = NULL;+	unsigned long l_flags;++	DPRINTF("%s()\n", __FUNCTION__);++	KASSERT(sc != NULL, ("hifn_newsession: null softc"));+	if (sidp == NULL || cri == NULL || sc == NULL) {+		DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);+		return (EINVAL);+	}++	HIFN_LOCK(sc);+	if (sc->sc_sessions == NULL) {+		ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),+				SLAB_ATOMIC);+		if (ses == NULL) {+			HIFN_UNLOCK(sc);+			return (ENOMEM);+		}+		sesn = 0;+		sc->sc_nsessions = 1;+	} else {+		for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {+			if (!sc->sc_sessions[sesn].hs_used) {+				ses = &sc->sc_sessions[sesn];+				break;+			}+		}++		if (ses == NULL) {+			sesn = sc->sc_nsessions;+			ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),+					SLAB_ATOMIC);+			if (ses == NULL) {+				HIFN_UNLOCK(sc);+				return (ENOMEM);+			}+			bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));+			bzero(sc->sc_sessions, sesn * sizeof(*ses));+			kfree(sc->sc_sessions);+			sc->sc_sessions = ses;+			ses = &sc->sc_sessions[sesn];+			sc->sc_nsessions++;+		}+	}+	HIFN_UNLOCK(sc);++	bzero(ses, sizeof(*ses));+	ses->hs_used = 1;++	for (c = cri; c != NULL; c = c->cri_next) {+		switch (c->cri_alg) {+		case CRYPTO_MD5:+		case CRYPTO_SHA1:+		case CRYPTO_MD5_HMAC:+		case CRYPTO_SHA1_HMAC:+			if (mac) {+				DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+				return (EINVAL);+			}+			mac = 1;+			ses->hs_mlen = c->cri_mlen;+			if (ses->hs_mlen == 0) {+				switch (c->cri_alg) {+				case CRYPTO_MD5:+				case CRYPTO_MD5_HMAC:+					ses->hs_mlen = 16;+					break;+				case CRYPTO_SHA1:+				case CRYPTO_SHA1_HMAC:+					ses->hs_mlen = 20;+					break;+				}+			}+			break;+		case CRYPTO_DES_CBC:+		case CRYPTO_3DES_CBC:+		case CRYPTO_AES_CBC:+			/* XXX this may read fewer, does it matter? */+			read_random(ses->hs_iv,+				c->cri_alg == CRYPTO_AES_CBC ?+					HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);+			/*FALLTHROUGH*/+		case CRYPTO_ARC4:+			if (cry) {+				DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+				return (EINVAL);+			}+			cry = 1;+			break;+		default:+			DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+			return (EINVAL);+		}+	}+	if (mac == 0 && cry == 0) {+		DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+		return (EINVAL);+	}++	*sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);++	return (0);+}++/*+ * Deallocate a session.+ * XXX this routine should run a zero'd mac/encrypt key into context ram.+ * XXX to blow away any keys already stored there.+ */+static int+hifn_freesession(device_t dev, u_int64_t tid)+{+	struct hifn_softc *sc = device_get_softc(dev);+	int session, error;+	u_int32_t sid = CRYPTO_SESID2LID(tid);+	unsigned long l_flags;++	DPRINTF("%s()\n", __FUNCTION__);++	KASSERT(sc != NULL, ("hifn_freesession: null softc"));+	if (sc == NULL) {+		DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+		return (EINVAL);+	}++	HIFN_LOCK(sc);+	session = HIFN_SESSION(sid);+	if (session < sc->sc_nsessions) {+		bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));+		error = 0;+	} else {+		DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+		error = EINVAL;+	}+	HIFN_UNLOCK(sc);++	return (error);+}++static int+hifn_process(device_t dev, struct cryptop *crp, int hint)+{+	struct hifn_softc *sc = device_get_softc(dev);+	struct hifn_command *cmd = NULL;+	int session, err, ivlen;+	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;++	DPRINTF("%s()\n", __FUNCTION__);++	if (crp == NULL || crp->crp_callback == NULL) {+		hifnstats.hst_invalid++;+		DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+		return (EINVAL);+	}+	session = HIFN_SESSION(crp->crp_sid);++	if (sc == NULL || session >= sc->sc_nsessions) {+		DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+		err = EINVAL;+		goto errout;+	}++	cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);+	if (cmd == NULL) {+		hifnstats.hst_nomem++;+		err = ENOMEM;+		goto errout;+	}+	memset(cmd, 0, sizeof(*cmd));++	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		cmd->src_skb = (struct sk_buff *)crp->crp_buf;+		cmd->dst_skb = (struct sk_buff *)crp->crp_buf;+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		cmd->src_io = (struct uio *)crp->crp_buf;+		cmd->dst_io = (struct uio *)crp->crp_buf;+	} else {+		cmd->src_buf = crp->crp_buf;+		cmd->dst_buf = crp->crp_buf;+	}++	crd1 = crp->crp_desc;+	if (crd1 == NULL) {+		DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+		err = EINVAL;+		goto errout;+	}+	crd2 = crd1->crd_next;++	if (crd2 == NULL) {+		if (crd1->crd_alg == CRYPTO_MD5_HMAC ||+		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||+		    crd1->crd_alg == CRYPTO_SHA1 ||+		    crd1->crd_alg == CRYPTO_MD5) {+			maccrd = crd1;+			enccrd = NULL;+		} else if (crd1->crd_alg == CRYPTO_DES_CBC ||+		    crd1->crd_alg == CRYPTO_3DES_CBC ||+		    crd1->crd_alg == CRYPTO_AES_CBC ||+		    crd1->crd_alg == CRYPTO_ARC4) {+			if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)+				cmd->base_masks |= HIFN_BASE_CMD_DECODE;+			maccrd = NULL;+			enccrd = crd1;+		} else {+			DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+			err = EINVAL;+			goto errout;+		}+	} else {+		if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||+                     crd1->crd_alg == CRYPTO_SHA1_HMAC ||+                     crd1->crd_alg == CRYPTO_MD5 ||+                     crd1->crd_alg == CRYPTO_SHA1) &&+		    (crd2->crd_alg == CRYPTO_DES_CBC ||+		     crd2->crd_alg == CRYPTO_3DES_CBC ||+		     crd2->crd_alg == CRYPTO_AES_CBC ||+		     crd2->crd_alg == CRYPTO_ARC4) &&+		    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {+			cmd->base_masks = HIFN_BASE_CMD_DECODE;+			maccrd = crd1;+			enccrd = crd2;+		} else if ((crd1->crd_alg == CRYPTO_DES_CBC ||+		     crd1->crd_alg == CRYPTO_ARC4 ||+		     crd1->crd_alg == CRYPTO_3DES_CBC ||+		     crd1->crd_alg == CRYPTO_AES_CBC) &&+		    (crd2->crd_alg == CRYPTO_MD5_HMAC ||+                     crd2->crd_alg == CRYPTO_SHA1_HMAC ||+                     crd2->crd_alg == CRYPTO_MD5 ||+                     crd2->crd_alg == CRYPTO_SHA1) &&+		    (crd1->crd_flags & CRD_F_ENCRYPT)) {+			enccrd = crd1;+			maccrd = crd2;+		} else {+			/*+			 * We cannot order the 7751 as requested+			 */+			DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);+			err = EINVAL;+			goto errout;+		}+	}++	if (enccrd) {+		cmd->enccrd = enccrd;+		cmd->base_masks |= HIFN_BASE_CMD_CRYPT;+		switch (enccrd->crd_alg) {+		case CRYPTO_ARC4:+			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;+			break;+		case CRYPTO_DES_CBC:+			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |+			    HIFN_CRYPT_CMD_MODE_CBC |+			    HIFN_CRYPT_CMD_NEW_IV;+			break;+		case CRYPTO_3DES_CBC:+			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |+			    HIFN_CRYPT_CMD_MODE_CBC |+			    HIFN_CRYPT_CMD_NEW_IV;+			break;+		case CRYPTO_AES_CBC:+			cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |+			    HIFN_CRYPT_CMD_MODE_CBC |+			    HIFN_CRYPT_CMD_NEW_IV;+			break;+		default:+			DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+			err = EINVAL;+			goto errout;+		}+		if (enccrd->crd_alg != CRYPTO_ARC4) {+			ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?+				HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);+			if (enccrd->crd_flags & CRD_F_ENCRYPT) {+				if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)+					bcopy(enccrd->crd_iv, cmd->iv, ivlen);+				else+					bcopy(sc->sc_sessions[session].hs_iv,+					    cmd->iv, ivlen);++				if ((enccrd->crd_flags & CRD_F_IV_PRESENT)+				    == 0) {+					crypto_copyback(crp->crp_flags,+					    crp->crp_buf, enccrd->crd_inject,+					    ivlen, cmd->iv);+				}+			} else {+				if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)+					bcopy(enccrd->crd_iv, cmd->iv, ivlen);+				else {+					crypto_copydata(crp->crp_flags,+					    crp->crp_buf, enccrd->crd_inject,+					    ivlen, cmd->iv);+				}+			}+		}++		if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)+			cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;+		cmd->ck = enccrd->crd_key;+		cmd->cklen = enccrd->crd_klen >> 3;+		cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;++		/* +		 * Need to specify the size for the AES key in the masks.+		 */+		if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==+		    HIFN_CRYPT_CMD_ALG_AES) {+			switch (cmd->cklen) {+			case 16:+				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;+				break;+			case 24:+				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;+				break;+			case 32:+				cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;+				break;+			default:+				DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);+				err = EINVAL;+				goto errout;+			}+		}+	}++	if (maccrd) {+		cmd->maccrd = maccrd;+		cmd->base_masks |= HIFN_BASE_CMD_MAC;++		switch (maccrd->crd_alg) {+		case CRYPTO_MD5:+			cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |+			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |+			    HIFN_MAC_CMD_POS_IPSEC;+                       break;+		case CRYPTO_MD5_HMAC:+			cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |+			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |+			    HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;+			break;+		case CRYPTO_SHA1:+			cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |+			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |+			    HIFN_MAC_CMD_POS_IPSEC;+			break;+		case CRYPTO_SHA1_HMAC:+			cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |+			    HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |+			    HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;+			break;+		}++		if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||+		     maccrd->crd_alg == CRYPTO_MD5_HMAC) {+			cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;+			bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);+			bzero(cmd->mac + (maccrd->crd_klen >> 3),+			    HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));+		}+	}++	cmd->crp = crp;+	cmd->session_num = session;+	cmd->softc = sc;++	err = hifn_crypto(sc, cmd, crp, hint);+	if (!err) {+		return 0;+	} else if (err == ERESTART) {+		/*+		 * There weren't enough resources to dispatch the request+		 * to the part.  Notify the caller so they'll requeue this+		 * request and resubmit it again soon.+		 */+#ifdef HIFN_DEBUG+		if (hifn_debug)+			device_printf(sc->sc_dev, "requeue request\n");+#endif+		kfree(cmd);+		sc->sc_needwakeup |= CRYPTO_SYMQ;+		return (err);+	}++errout:+	if (cmd != NULL)+		kfree(cmd);+	if (err == EINVAL)+		hifnstats.hst_invalid++;+	else+		hifnstats.hst_nomem++;+	crp->crp_etype = err;+	crypto_done(crp);+	return (err);+}++static void+hifn_abort(struct hifn_softc *sc)+{+	struct hifn_dma *dma = sc->sc_dma;+	struct hifn_command *cmd;+	struct cryptop *crp;+	int i, u;++	DPRINTF("%s()\n", __FUNCTION__);++	i = dma->resk; u = dma->resu;+	while (u != 0) {+		cmd = dma->hifn_commands[i];+		KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));+		dma->hifn_commands[i] = NULL;+		crp = cmd->crp;++		if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {+			/* Salvage what we can. */+			u_int8_t *macbuf;++			if (cmd->base_masks & HIFN_BASE_CMD_MAC) {+				macbuf = dma->result_bufs[i];+				macbuf += 12;+			} else+				macbuf = NULL;+			hifnstats.hst_opackets++;+			hifn_callback(sc, cmd, macbuf);+		} else {+#if 0+			if (cmd->src_map == cmd->dst_map) {+				bus_dmamap_sync(sc->sc_dmat, cmd->src_map,+				    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);+			} else {+				bus_dmamap_sync(sc->sc_dmat, cmd->src_map,+				    BUS_DMASYNC_POSTWRITE);+				bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,+				    BUS_DMASYNC_POSTREAD);+			}+#endif++			if (cmd->src_skb != cmd->dst_skb) {+#ifdef NOTYET+				m_freem(cmd->src_m);+				crp->crp_buf = (caddr_t)cmd->dst_m;+#else+				device_printf(sc->sc_dev,+						"%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",+						__FILE__, __LINE__);+#endif+			}++			/* non-shared buffers cannot be restarted */+			if (cmd->src_map != cmd->dst_map) {+				/*+				 * XXX should be EAGAIN, delayed until+				 * after the reset.+				 */+				crp->crp_etype = ENOMEM;+				pci_unmap_buf(sc, &cmd->dst);+			} else+				crp->crp_etype = ENOMEM;++			pci_unmap_buf(sc, &cmd->src);++			kfree(cmd);+			if (crp->crp_etype != EAGAIN)+				crypto_done(crp);+		}++		if (++i == HIFN_D_RES_RSIZE)+			i = 0;+		u--;+	}+	dma->resk = i; dma->resu = u;++	hifn_reset_board(sc, 1);+	hifn_init_dma(sc);+	hifn_init_pci_registers(sc);+}++static void+hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)+{+	struct hifn_dma *dma = sc->sc_dma;+	struct cryptop *crp = cmd->crp;+	struct cryptodesc *crd;+	int i, u, ivlen;++	DPRINTF("%s()\n", __FUNCTION__);++#if 0+	if (cmd->src_map == cmd->dst_map) {+		bus_dmamap_sync(sc->sc_dmat, cmd->src_map,+		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);+	} else {+		bus_dmamap_sync(sc->sc_dmat, cmd->src_map,+		    BUS_DMASYNC_POSTWRITE);+		bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,+		    BUS_DMASYNC_POSTREAD);+	}+#endif++	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		if (cmd->src_skb != cmd->dst_skb) {+#ifdef NOTYET+			crp->crp_buf = (caddr_t)cmd->dst_m;+			totlen = cmd->src_mapsize;+			for (m = cmd->dst_m; m != NULL; m = m->m_next) {+				if (totlen < m->m_len) {+					m->m_len = totlen;+					totlen = 0;+				} else+					totlen -= m->m_len;+			}+			cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;+			m_freem(cmd->src_m);+#else+			device_printf(sc->sc_dev,+					"%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",+					__FILE__, __LINE__);+#endif+		}+	}++	if (cmd->sloplen != 0) {+		crypto_copyback(crp->crp_flags, crp->crp_buf,+		    cmd->src_mapsize - cmd->sloplen, cmd->sloplen,+		    (caddr_t)&dma->slop[cmd->slopidx]);+	}++	i = dma->dstk; u = dma->dstu;+	while (u != 0) {+		if (i == HIFN_D_DST_RSIZE)+			i = 0;+#if 0+		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,+		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);+#endif+		if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {+#if 0+			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);+#endif+			break;+		}+		i++, u--;+	}+	dma->dstk = i; dma->dstu = u;++	hifnstats.hst_obytes += cmd->dst_mapsize;++	if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==+	    HIFN_BASE_CMD_CRYPT) {+		for (crd = crp->crp_desc; crd; crd = crd->crd_next) {+			if (crd->crd_alg != CRYPTO_DES_CBC &&+			    crd->crd_alg != CRYPTO_3DES_CBC &&+			    crd->crd_alg != CRYPTO_AES_CBC)+				continue;+			ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?+				HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);+			crypto_copydata(crp->crp_flags, crp->crp_buf,+			    crd->crd_skip + crd->crd_len - ivlen, ivlen,+			    cmd->softc->sc_sessions[cmd->session_num].hs_iv);+			break;+		}+	}++	if (macbuf != NULL) {+		for (crd = crp->crp_desc; crd; crd = crd->crd_next) {+                        int len;++			if (crd->crd_alg != CRYPTO_MD5 &&+			    crd->crd_alg != CRYPTO_SHA1 &&+			    crd->crd_alg != CRYPTO_MD5_HMAC &&+			    crd->crd_alg != CRYPTO_SHA1_HMAC) {+				continue;+			}+			len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;+			crypto_copyback(crp->crp_flags, crp->crp_buf,+			    crd->crd_inject, len, macbuf);+			break;+		}+	}++	if (cmd->src_map != cmd->dst_map)+		pci_unmap_buf(sc, &cmd->dst);+	pci_unmap_buf(sc, &cmd->src);+	kfree(cmd);+	crypto_done(crp);+}++/*+ * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0+ * and Group 1 registers; avoid conditions that could create+ * burst writes by doing a read in between the writes.+ *+ * NB: The read we interpose is always to the same register;+ *     we do this because reading from an arbitrary (e.g. last)+ *     register may not always work.+ */+static void+hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)+{+	if (sc->sc_flags & HIFN_IS_7811) {+		if (sc->sc_bar0_lastreg == reg - 4)+			readl(sc->sc_bar0 + HIFN_0_PUCNFG);+		sc->sc_bar0_lastreg = reg;+	}+	writel(val, sc->sc_bar0 + reg);+}++static void+hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)+{+	if (sc->sc_flags & HIFN_IS_7811) {+		if (sc->sc_bar1_lastreg == reg - 4)+			readl(sc->sc_bar1 + HIFN_1_REVID);+		sc->sc_bar1_lastreg = reg;+	}+	writel(val, sc->sc_bar1 + reg);+}+++static struct pci_device_id hifn_pci_tbl[] = {+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	/*+	 * Other vendors share this PCI ID as well, such as+	 * http://www.powercrypt.com, and obviously they also+	 * use the same key.+	 */+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ 0, 0, 0, 0, 0, 0, }+};+MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);++static struct pci_driver hifn_driver = {+	.name         = "hifn",+	.id_table     = hifn_pci_tbl,+	.probe        =	hifn_probe,+	.remove       = hifn_remove,+	/* add PM stuff here one day */+};++static int __init hifn_init (void)+{+	struct hifn_softc *sc = NULL;+	int rc;++	DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);++	rc = pci_register_driver(&hifn_driver);+	pci_register_driver_compat(&hifn_driver, rc);++	return rc;+}++static void __exit hifn_exit (void)+{+	pci_unregister_driver(&hifn_driver);+}++module_init(hifn_init);+module_exit(hifn_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.36/crypto/ocf/hifn/hifn7751reg.h--- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751reg.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/hifn7751reg.h	2010-11-09 20:28:04.792495416 +0100@@ -0,0 +1,540 @@+/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */+/*	$OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $	*/++/*-+ * Invertex AEON / Hifn 7751 driver+ * Copyright (c) 1999 Invertex Inc. All rights reserved.+ * Copyright (c) 1999 Theo de Raadt+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.+ *			http://www.netsec.net+ *+ * Please send any comments, feedback, bug-fixes, or feature requests to+ * software@invertex.com.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+ */+#ifndef __HIFN_H__+#define	__HIFN_H__++/*+ * Some PCI configuration space offset defines.  The names were made+ * identical to the names used by the Linux kernel.+ */+#define	HIFN_BAR0		PCIR_BAR(0)	/* PUC register map */+#define	HIFN_BAR1		PCIR_BAR(1)	/* DMA register map */+#define	HIFN_TRDY_TIMEOUT	0x40+#define	HIFN_RETRY_TIMEOUT	0x41++/*+ * PCI vendor and device identifiers+ * (the names are preserved from their OpenBSD source).+ */+#define	PCI_VENDOR_HIFN		0x13a3		/* Hifn */+#define	PCI_PRODUCT_HIFN_7751	0x0005		/* 7751 */+#define	PCI_PRODUCT_HIFN_6500	0x0006		/* 6500 */+#define	PCI_PRODUCT_HIFN_7811	0x0007		/* 7811 */+#define	PCI_PRODUCT_HIFN_7855	0x001f		/* 7855 */+#define	PCI_PRODUCT_HIFN_7951	0x0012		/* 7951 */+#define	PCI_PRODUCT_HIFN_7955	0x0020		/* 7954/7955 */+#define	PCI_PRODUCT_HIFN_7956	0x001d		/* 7956 */++#define	PCI_VENDOR_INVERTEX	0x14e1		/* Invertex */+#define	PCI_PRODUCT_INVERTEX_AEON 0x0005	/* AEON */++#define	PCI_VENDOR_NETSEC	0x1660		/* NetSec */+#define	PCI_PRODUCT_NETSEC_7751	0x7751		/* 7751 */++/*+ * The values below should multiple of 4 -- and be large enough to handle+ * any command the driver implements.+ *+ * MAX_COMMAND = base command + mac command + encrypt command ++ *			mac-key + rc4-key+ * MAX_RESULT  = base result + mac result + mac + encrypt result+ *			+ *+ */+#define	HIFN_MAX_COMMAND	(8 + 8 + 8 + 64 + 260)+#define	HIFN_MAX_RESULT		(8 + 4 + 20 + 4)++/*+ * hifn_desc_t+ *+ * Holds an individual descriptor for any of the rings.+ */+typedef struct hifn_desc {+	volatile u_int32_t l;		/* length and status bits */+	volatile u_int32_t p;+} hifn_desc_t;++/*+ * Masks for the "length" field of struct hifn_desc.+ */+#define	HIFN_D_LENGTH		0x0000ffff	/* length bit mask */+#define	HIFN_D_MASKDONEIRQ	0x02000000	/* mask the done interrupt */+#define	HIFN_D_DESTOVER		0x04000000	/* destination overflow */+#define	HIFN_D_OVER		0x08000000	/* overflow */+#define	HIFN_D_LAST		0x20000000	/* last descriptor in chain */+#define	HIFN_D_JUMP		0x40000000	/* jump descriptor */+#define	HIFN_D_VALID		0x80000000	/* valid bit */+++/*+ * Processing Unit Registers (offset from BASEREG0)+ */+#define	HIFN_0_PUDATA		0x00	/* Processing Unit Data */+#define	HIFN_0_PUCTRL		0x04	/* Processing Unit Control */+#define	HIFN_0_PUISR		0x08	/* Processing Unit Interrupt Status */+#define	HIFN_0_PUCNFG		0x0c	/* Processing Unit Configuration */+#define	HIFN_0_PUIER		0x10	/* Processing Unit Interrupt Enable */+#define	HIFN_0_PUSTAT		0x14	/* Processing Unit Status/Chip ID */+#define	HIFN_0_FIFOSTAT		0x18	/* FIFO Status */+#define	HIFN_0_FIFOCNFG		0x1c	/* FIFO Configuration */+#define	HIFN_0_PUCTRL2		0x28	/* Processing Unit Control (2nd map) */+#define	HIFN_0_MUTE1		0x80+#define	HIFN_0_MUTE2		0x90+#define	HIFN_0_SPACESIZE	0x100	/* Register space size */++/* Processing Unit Control Register (HIFN_0_PUCTRL) */+#define	HIFN_PUCTRL_CLRSRCFIFO	0x0010	/* clear source fifo */+#define	HIFN_PUCTRL_STOP	0x0008	/* stop pu */+#define	HIFN_PUCTRL_LOCKRAM	0x0004	/* lock ram */+#define	HIFN_PUCTRL_DMAENA	0x0002	/* enable dma */+#define	HIFN_PUCTRL_RESET	0x0001	/* Reset processing unit */++/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */+#define	HIFN_PUISR_CMDINVAL	0x8000	/* Invalid command interrupt */+#define	HIFN_PUISR_DATAERR	0x4000	/* Data error interrupt */+#define	HIFN_PUISR_SRCFIFO	0x2000	/* Source FIFO ready interrupt */+#define	HIFN_PUISR_DSTFIFO	0x1000	/* Destination FIFO ready interrupt */+#define	HIFN_PUISR_DSTOVER	0x0200	/* Destination overrun interrupt */+#define	HIFN_PUISR_SRCCMD	0x0080	/* Source command interrupt */+#define	HIFN_PUISR_SRCCTX	0x0040	/* Source context interrupt */+#define	HIFN_PUISR_SRCDATA	0x0020	/* Source data interrupt */+#define	HIFN_PUISR_DSTDATA	0x0010	/* Destination data interrupt */+#define	HIFN_PUISR_DSTRESULT	0x0004	/* Destination result interrupt */++/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */+#define	HIFN_PUCNFG_DRAMMASK	0xe000	/* DRAM size mask */+#define	HIFN_PUCNFG_DSZ_256K	0x0000	/* 256k dram */+#define	HIFN_PUCNFG_DSZ_512K	0x2000	/* 512k dram */+#define	HIFN_PUCNFG_DSZ_1M	0x4000	/* 1m dram */+#define	HIFN_PUCNFG_DSZ_2M	0x6000	/* 2m dram */+#define	HIFN_PUCNFG_DSZ_4M	0x8000	/* 4m dram */+#define	HIFN_PUCNFG_DSZ_8M	0xa000	/* 8m dram */+#define	HIFN_PUNCFG_DSZ_16M	0xc000	/* 16m dram */+#define	HIFN_PUCNFG_DSZ_32M	0xe000	/* 32m dram */+#define	HIFN_PUCNFG_DRAMREFRESH	0x1800	/* DRAM refresh rate mask */+#define	HIFN_PUCNFG_DRFR_512	0x0000	/* 512 divisor of ECLK */+#define	HIFN_PUCNFG_DRFR_256	0x0800	/* 256 divisor of ECLK */+#define	HIFN_PUCNFG_DRFR_128	0x1000	/* 128 divisor of ECLK */+#define	HIFN_PUCNFG_TCALLPHASES	0x0200	/* your guess is as good as mine... */+#define	HIFN_PUCNFG_TCDRVTOTEM	0x0100	/* your guess is as good as mine... */+#define	HIFN_PUCNFG_BIGENDIAN	0x0080	/* DMA big endian mode */+#define	HIFN_PUCNFG_BUS32	0x0040	/* Bus width 32bits */+#define	HIFN_PUCNFG_BUS16	0x0000	/* Bus width 16 bits */+#define	HIFN_PUCNFG_CHIPID	0x0020	/* Allow chipid from PUSTAT */+#define	HIFN_PUCNFG_DRAM	0x0010	/* Context RAM is DRAM */+#define	HIFN_PUCNFG_SRAM	0x0000	/* Context RAM is SRAM */+#define	HIFN_PUCNFG_COMPSING	0x0004	/* Enable single compression context */+#define	HIFN_PUCNFG_ENCCNFG	0x0002	/* Encryption configuration */++/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */+#define	HIFN_PUIER_CMDINVAL	0x8000	/* Invalid command interrupt */+#define	HIFN_PUIER_DATAERR	0x4000	/* Data error interrupt */+#define	HIFN_PUIER_SRCFIFO	0x2000	/* Source FIFO ready interrupt */+#define	HIFN_PUIER_DSTFIFO	0x1000	/* Destination FIFO ready interrupt */+#define	HIFN_PUIER_DSTOVER	0x0200	/* Destination overrun interrupt */+#define	HIFN_PUIER_SRCCMD	0x0080	/* Source command interrupt */+#define	HIFN_PUIER_SRCCTX	0x0040	/* Source context interrupt */+#define	HIFN_PUIER_SRCDATA	0x0020	/* Source data interrupt */+#define	HIFN_PUIER_DSTDATA	0x0010	/* Destination data interrupt */+#define	HIFN_PUIER_DSTRESULT	0x0004	/* Destination result interrupt */++/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */+#define	HIFN_PUSTAT_CMDINVAL	0x8000	/* Invalid command interrupt */+#define	HIFN_PUSTAT_DATAERR	0x4000	/* Data error interrupt */+#define	HIFN_PUSTAT_SRCFIFO	0x2000	/* Source FIFO ready interrupt */+#define	HIFN_PUSTAT_DSTFIFO	0x1000	/* Destination FIFO ready interrupt */+#define	HIFN_PUSTAT_DSTOVER	0x0200	/* Destination overrun interrupt */+#define	HIFN_PUSTAT_SRCCMD	0x0080	/* Source command interrupt */+#define	HIFN_PUSTAT_SRCCTX	0x0040	/* Source context interrupt */+#define	HIFN_PUSTAT_SRCDATA	0x0020	/* Source data interrupt */+#define	HIFN_PUSTAT_DSTDATA	0x0010	/* Destination data interrupt */+#define	HIFN_PUSTAT_DSTRESULT	0x0004	/* Destination result interrupt */+#define	HIFN_PUSTAT_CHIPREV	0x00ff	/* Chip revision mask */+#define	HIFN_PUSTAT_CHIPENA	0xff00	/* Chip enabled mask */+#define	HIFN_PUSTAT_ENA_2	0x1100	/* Level 2 enabled */+#define	HIFN_PUSTAT_ENA_1	0x1000	/* Level 1 enabled */+#define	HIFN_PUSTAT_ENA_0	0x3000	/* Level 0 enabled */+#define	HIFN_PUSTAT_REV_2	0x0020	/* 7751 PT6/2 */+#define	HIFN_PUSTAT_REV_3	0x0030	/* 7751 PT6/3 */++/* FIFO Status Register (HIFN_0_FIFOSTAT) */+#define	HIFN_FIFOSTAT_SRC	0x7f00	/* Source FIFO available */+#define	HIFN_FIFOSTAT_DST	0x007f	/* Destination FIFO available */++/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */+#define	HIFN_FIFOCNFG_THRESHOLD	0x0400	/* must be written as this value */++/*+ * DMA Interface Registers (offset from BASEREG1)+ */+#define	HIFN_1_DMA_CRAR		0x0c	/* DMA Command Ring Address */+#define	HIFN_1_DMA_SRAR		0x1c	/* DMA Source Ring Address */+#define	HIFN_1_DMA_RRAR		0x2c	/* DMA Result Ring Address */+#define	HIFN_1_DMA_DRAR		0x3c	/* DMA Destination Ring Address */+#define	HIFN_1_DMA_CSR		0x40	/* DMA Status and Control */+#define	HIFN_1_DMA_IER		0x44	/* DMA Interrupt Enable */+#define	HIFN_1_DMA_CNFG		0x48	/* DMA Configuration */+#define	HIFN_1_PLL		0x4c	/* 7955/7956: PLL config */+#define	HIFN_1_7811_RNGENA	0x60	/* 7811: rng enable */+#define	HIFN_1_7811_RNGCFG	0x64	/* 7811: rng config */+#define	HIFN_1_7811_RNGDAT	0x68	/* 7811: rng data */+#define	HIFN_1_7811_RNGSTS	0x6c	/* 7811: rng status */+#define	HIFN_1_DMA_CNFG2	0x6c	/* 7955/7956: dma config #2 */+#define	HIFN_1_7811_MIPSRST	0x94	/* 7811: MIPS reset */+#define	HIFN_1_REVID		0x98	/* Revision ID */++#define	HIFN_1_PUB_RESET	0x204	/* Public/RNG Reset */+#define	HIFN_1_PUB_BASE		0x300	/* Public Base Address */+#define	HIFN_1_PUB_OPLEN	0x304	/* 7951-compat Public Operand Length */+#define	HIFN_1_PUB_OP		0x308	/* 7951-compat Public Operand */+#define	HIFN_1_PUB_STATUS	0x30c	/* 7951-compat Public Status */+#define	HIFN_1_PUB_IEN		0x310	/* Public Interrupt enable */+#define	HIFN_1_RNG_CONFIG	0x314	/* RNG config */+#define	HIFN_1_RNG_DATA		0x318	/* RNG data */+#define	HIFN_1_PUB_MODE		0x320	/* PK mode */+#define	HIFN_1_PUB_FIFO_OPLEN	0x380	/* first element of oplen fifo */+#define	HIFN_1_PUB_FIFO_OP	0x384	/* first element of op fifo */+#define	HIFN_1_PUB_MEM		0x400	/* start of Public key memory */+#define	HIFN_1_PUB_MEMEND	0xbff	/* end of Public key memory */++/* DMA Status and Control Register (HIFN_1_DMA_CSR) */+#define	HIFN_DMACSR_D_CTRLMASK	0xc0000000	/* Destinition Ring Control */+#define	HIFN_DMACSR_D_CTRL_NOP	0x00000000	/* Dest. Control: no-op */+#define	HIFN_DMACSR_D_CTRL_DIS	0x40000000	/* Dest. Control: disable */+#define	HIFN_DMACSR_D_CTRL_ENA	0x80000000	/* Dest. Control: enable */+#define	HIFN_DMACSR_D_ABORT	0x20000000	/* Destinition Ring PCIAbort */+#define	HIFN_DMACSR_D_DONE	0x10000000	/* Destinition Ring Done */+#define	HIFN_DMACSR_D_LAST	0x08000000	/* Destinition Ring Last */+#define	HIFN_DMACSR_D_WAIT	0x04000000	/* Destinition Ring Waiting */+#define	HIFN_DMACSR_D_OVER	0x02000000	/* Destinition Ring Overflow */+#define	HIFN_DMACSR_R_CTRL	0x00c00000	/* Result Ring Control */+#define	HIFN_DMACSR_R_CTRL_NOP	0x00000000	/* Result Control: no-op */+#define	HIFN_DMACSR_R_CTRL_DIS	0x00400000	/* Result Control: disable */+#define	HIFN_DMACSR_R_CTRL_ENA	0x00800000	/* Result Control: enable */+#define	HIFN_DMACSR_R_ABORT	0x00200000	/* Result Ring PCI Abort */+#define	HIFN_DMACSR_R_DONE	0x00100000	/* Result Ring Done */+#define	HIFN_DMACSR_R_LAST	0x00080000	/* Result Ring Last */+#define	HIFN_DMACSR_R_WAIT	0x00040000	/* Result Ring Waiting */+#define	HIFN_DMACSR_R_OVER	0x00020000	/* Result Ring Overflow */+#define	HIFN_DMACSR_S_CTRL	0x0000c000	/* Source Ring Control */+#define	HIFN_DMACSR_S_CTRL_NOP	0x00000000	/* Source Control: no-op */+#define	HIFN_DMACSR_S_CTRL_DIS	0x00004000	/* Source Control: disable */+#define	HIFN_DMACSR_S_CTRL_ENA	0x00008000	/* Source Control: enable */+#define	HIFN_DMACSR_S_ABORT	0x00002000	/* Source Ring PCI Abort */+#define	HIFN_DMACSR_S_DONE	0x00001000	/* Source Ring Done */+#define	HIFN_DMACSR_S_LAST	0x00000800	/* Source Ring Last */+#define	HIFN_DMACSR_S_WAIT	0x00000400	/* Source Ring Waiting */+#define	HIFN_DMACSR_ILLW	0x00000200	/* Illegal write (7811 only) */+#define	HIFN_DMACSR_ILLR	0x00000100	/* Illegal read (7811 only) */+#define	HIFN_DMACSR_C_CTRL	0x000000c0	/* Command Ring Control */+#define	HIFN_DMACSR_C_CTRL_NOP	0x00000000	/* Command Control: no-op */+#define	HIFN_DMACSR_C_CTRL_DIS	0x00000040	/* Command Control: disable */+#define	HIFN_DMACSR_C_CTRL_ENA	0x00000080	/* Command Control: enable */+#define	HIFN_DMACSR_C_ABORT	0x00000020	/* Command Ring PCI Abort */+#define	HIFN_DMACSR_C_DONE	0x00000010	/* Command Ring Done */+#define	HIFN_DMACSR_C_LAST	0x00000008	/* Command Ring Last */+#define	HIFN_DMACSR_C_WAIT	0x00000004	/* Command Ring Waiting */+#define	HIFN_DMACSR_PUBDONE	0x00000002	/* Public op done (7951 only) */+#define	HIFN_DMACSR_ENGINE	0x00000001	/* Command Ring Engine IRQ */++/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */+#define	HIFN_DMAIER_D_ABORT	0x20000000	/* Destination Ring PCIAbort */+#define	HIFN_DMAIER_D_DONE	0x10000000	/* Destination Ring Done */+#define	HIFN_DMAIER_D_LAST	0x08000000	/* Destination Ring Last */+#define	HIFN_DMAIER_D_WAIT	0x04000000	/* Destination Ring Waiting */+#define	HIFN_DMAIER_D_OVER	0x02000000	/* Destination Ring Overflow */+#define	HIFN_DMAIER_R_ABORT	0x00200000	/* Result Ring PCI Abort */+#define	HIFN_DMAIER_R_DONE	0x00100000	/* Result Ring Done */+#define	HIFN_DMAIER_R_LAST	0x00080000	/* Result Ring Last */+#define	HIFN_DMAIER_R_WAIT	0x00040000	/* Result Ring Waiting */+#define	HIFN_DMAIER_R_OVER	0x00020000	/* Result Ring Overflow */+#define	HIFN_DMAIER_S_ABORT	0x00002000	/* Source Ring PCI Abort */+#define	HIFN_DMAIER_S_DONE	0x00001000	/* Source Ring Done */+#define	HIFN_DMAIER_S_LAST	0x00000800	/* Source Ring Last */+#define	HIFN_DMAIER_S_WAIT	0x00000400	/* Source Ring Waiting */+#define	HIFN_DMAIER_ILLW	0x00000200	/* Illegal write (7811 only) */+#define	HIFN_DMAIER_ILLR	0x00000100	/* Illegal read (7811 only) */+#define	HIFN_DMAIER_C_ABORT	0x00000020	/* Command Ring PCI Abort */+#define	HIFN_DMAIER_C_DONE	0x00000010	/* Command Ring Done */+#define	HIFN_DMAIER_C_LAST	0x00000008	/* Command Ring Last */+#define	HIFN_DMAIER_C_WAIT	0x00000004	/* Command Ring Waiting */+#define	HIFN_DMAIER_PUBDONE	0x00000002	/* public op done (7951 only) */+#define	HIFN_DMAIER_ENGINE	0x00000001	/* Engine IRQ */++/* DMA Configuration Register (HIFN_1_DMA_CNFG) */+#define	HIFN_DMACNFG_BIGENDIAN	0x10000000	/* big endian mode */+#define	HIFN_DMACNFG_POLLFREQ	0x00ff0000	/* Poll frequency mask */+#define	HIFN_DMACNFG_UNLOCK	0x00000800+#define	HIFN_DMACNFG_POLLINVAL	0x00000700	/* Invalid Poll Scalar */+#define	HIFN_DMACNFG_LAST	0x00000010	/* Host control LAST bit */+#define	HIFN_DMACNFG_MODE	0x00000004	/* DMA mode */+#define	HIFN_DMACNFG_DMARESET	0x00000002	/* DMA Reset # */+#define	HIFN_DMACNFG_MSTRESET	0x00000001	/* Master Reset # */++/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */+#define	HIFN_DMACNFG2_PKSWAP32	(1 << 19)	/* swap the OPLEN/OP reg */+#define	HIFN_DMACNFG2_PKSWAP8	(1 << 18)	/* swap the bits of OPLEN/OP */+#define	HIFN_DMACNFG2_BAR0_SWAP32 (1<<17)	/* swap the bytes of BAR0 */+#define	HIFN_DMACNFG2_BAR1_SWAP8 (1<<16)	/* swap the bits  of BAR0 */+#define	HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12+#define	HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8+#define	HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4+#define	HIFN_DMACNFG2_TGT_READ_BURST_SHIFT  0++/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */+#define	HIFN_7811_RNGENA_ENA	0x00000001	/* enable RNG */++/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */+#define	HIFN_7811_RNGCFG_PRE1	0x00000f00	/* first prescalar */+#define	HIFN_7811_RNGCFG_OPRE	0x00000080	/* output prescalar */+#define	HIFN_7811_RNGCFG_DEFL	0x00000f80	/* 2 words/ 1/100 sec */++/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */+#define	HIFN_7811_RNGSTS_RDY	0x00004000	/* two numbers in FIFO */+#define	HIFN_7811_RNGSTS_UFL	0x00001000	/* rng underflow */++/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */+#define	HIFN_MIPSRST_BAR2SIZE	0xffff0000	/* sdram size */+#define	HIFN_MIPSRST_GPRAMINIT	0x00008000	/* gpram can be accessed */+#define	HIFN_MIPSRST_CRAMINIT	0x00004000	/* ctxram can be accessed */+#define	HIFN_MIPSRST_LED2	0x00000400	/* external LED2 */+#define	HIFN_MIPSRST_LED1	0x00000200	/* external LED1 */+#define	HIFN_MIPSRST_LED0	0x00000100	/* external LED0 */+#define	HIFN_MIPSRST_MIPSDIS	0x00000004	/* disable MIPS */+#define	HIFN_MIPSRST_MIPSRST	0x00000002	/* warm reset MIPS */+#define	HIFN_MIPSRST_MIPSCOLD	0x00000001	/* cold reset MIPS */++/* Public key reset register (HIFN_1_PUB_RESET) */+#define	HIFN_PUBRST_RESET	0x00000001	/* reset public/rng unit */++/* Public operation register (HIFN_1_PUB_OP) */+#define	HIFN_PUBOP_AOFFSET	0x0000003e	/* A offset */+#define	HIFN_PUBOP_BOFFSET	0x00000fc0	/* B offset */+#define	HIFN_PUBOP_MOFFSET	0x0003f000	/* M offset */+#define	HIFN_PUBOP_OP_MASK	0x003c0000	/* Opcode: */+#define	HIFN_PUBOP_OP_NOP	0x00000000	/*  NOP */+#define	HIFN_PUBOP_OP_ADD	0x00040000	/*  ADD */+#define	HIFN_PUBOP_OP_ADDC	0x00080000	/*  ADD w/carry */+#define	HIFN_PUBOP_OP_SUB	0x000c0000	/*  SUB */+#define	HIFN_PUBOP_OP_SUBC	0x00100000	/*  SUB w/carry */+#define	HIFN_PUBOP_OP_MODADD	0x00140000	/*  Modular ADD */+#define	HIFN_PUBOP_OP_MODSUB	0x00180000	/*  Modular SUB */+#define	HIFN_PUBOP_OP_INCA	0x001c0000	/*  INC A */+#define	HIFN_PUBOP_OP_DECA	0x00200000	/*  DEC A */+#define	HIFN_PUBOP_OP_MULT	0x00240000	/*  MULT */+#define	HIFN_PUBOP_OP_MODMULT	0x00280000	/*  Modular MULT */+#define	HIFN_PUBOP_OP_MODRED	0x002c0000	/*  Modular Red */+#define	HIFN_PUBOP_OP_MODEXP	0x00300000	/*  Modular Exp */++/* Public operand length register (HIFN_1_PUB_OPLEN) */+#define	HIFN_PUBOPLEN_MODLEN	0x0000007f+#define	HIFN_PUBOPLEN_EXPLEN	0x0003ff80+#define	HIFN_PUBOPLEN_REDLEN	0x003c0000++/* Public status register (HIFN_1_PUB_STATUS) */+#define	HIFN_PUBSTS_DONE	0x00000001	/* operation done */+#define	HIFN_PUBSTS_CARRY	0x00000002	/* carry */+#define	HIFN_PUBSTS_FIFO_EMPTY	0x00000100	/* fifo empty */+#define	HIFN_PUBSTS_FIFO_FULL	0x00000200	/* fifo full */+#define	HIFN_PUBSTS_FIFO_OVFL	0x00000400	/* fifo overflow */+#define	HIFN_PUBSTS_FIFO_WRITE	0x000f0000	/* fifo write */+#define	HIFN_PUBSTS_FIFO_READ	0x0f000000	/* fifo read */++/* Public interrupt enable register (HIFN_1_PUB_IEN) */+#define	HIFN_PUBIEN_DONE	0x00000001	/* operation done interrupt */++/* Random number generator config register (HIFN_1_RNG_CONFIG) */+#define	HIFN_RNGCFG_ENA		0x00000001	/* enable rng */++/*+ * Register offsets in register set 1+ */++#define	HIFN_UNLOCK_SECRET1	0xf4+#define	HIFN_UNLOCK_SECRET2	0xfc++/*+ * PLL config register+ *+ * This register is present only on 7954/7955/7956 parts. It must be+ * programmed according to the bus interface method used by the h/w.+ * Note that the parts require a stable clock.  Since the PCI clock+ * may vary the reference clock must usually be used.  To avoid+ * overclocking the core logic, setup must be done carefully, refer+ * to the driver for details.  The exact multiplier required varies+ * by part and system configuration; refer to the Hifn documentation.+ */+#define	HIFN_PLL_REF_SEL	0x00000001	/* REF/HBI clk selection */+#define	HIFN_PLL_BP		0x00000002	/* bypass (used during setup) */+/* bit 2 reserved */+#define	HIFN_PLL_PK_CLK_SEL	0x00000008	/* public key clk select */+#define	HIFN_PLL_PE_CLK_SEL	0x00000010	/* packet engine clk select */+/* bits 5-9 reserved */+#define	HIFN_PLL_MBSET		0x00000400	/* must be set to 1 */+#define	HIFN_PLL_ND		0x00003800	/* Fpll_ref multiplier select */+#define	HIFN_PLL_ND_SHIFT	11+#define	HIFN_PLL_ND_2		0x00000000	/* 2x */+#define	HIFN_PLL_ND_4		0x00000800	/* 4x */+#define	HIFN_PLL_ND_6		0x00001000	/* 6x */+#define	HIFN_PLL_ND_8		0x00001800	/* 8x */+#define	HIFN_PLL_ND_10		0x00002000	/* 10x */+#define	HIFN_PLL_ND_12		0x00002800	/* 12x */+/* bits 14-15 reserved */+#define	HIFN_PLL_IS		0x00010000	/* charge pump current select */+/* bits 17-31 reserved */++/*+ * Board configuration specifies only these bits.+ */+#define	HIFN_PLL_CONFIG		(HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)++/*+ * Public Key Engine Mode Register+ */+#define	HIFN_PKMODE_HOSTINVERT	(1 << 0)	/* HOST INVERT */+#define	HIFN_PKMODE_ENHANCED	(1 << 1)	/* Enable enhanced mode */+++/*********************************************************************+ * Structs for board commands + *+ *********************************************************************/++/*+ * Structure to help build up the command data structure.+ */+typedef struct hifn_base_command {+	volatile u_int16_t masks;+	volatile u_int16_t session_num;+	volatile u_int16_t total_source_count;+	volatile u_int16_t total_dest_count;+} hifn_base_command_t;++#define	HIFN_BASE_CMD_MAC		0x0400+#define	HIFN_BASE_CMD_CRYPT		0x0800+#define	HIFN_BASE_CMD_DECODE		0x2000+#define	HIFN_BASE_CMD_SRCLEN_M		0xc000+#define	HIFN_BASE_CMD_SRCLEN_S		14+#define	HIFN_BASE_CMD_DSTLEN_M		0x3000+#define	HIFN_BASE_CMD_DSTLEN_S		12+#define	HIFN_BASE_CMD_LENMASK_HI	0x30000+#define	HIFN_BASE_CMD_LENMASK_LO	0x0ffff++/*+ * Structure to help build up the command data structure.+ */+typedef struct hifn_crypt_command {+	volatile u_int16_t masks;+	volatile u_int16_t header_skip;+	volatile u_int16_t source_count;+	volatile u_int16_t reserved;+} hifn_crypt_command_t;++#define	HIFN_CRYPT_CMD_ALG_MASK		0x0003		/* algorithm: */+#define	HIFN_CRYPT_CMD_ALG_DES		0x0000		/*   DES */+#define	HIFN_CRYPT_CMD_ALG_3DES		0x0001		/*   3DES */+#define	HIFN_CRYPT_CMD_ALG_RC4		0x0002		/*   RC4 */+#define	HIFN_CRYPT_CMD_ALG_AES		0x0003		/*   AES */+#define	HIFN_CRYPT_CMD_MODE_MASK	0x0018		/* Encrypt mode: */+#define	HIFN_CRYPT_CMD_MODE_ECB		0x0000		/*   ECB */+#define	HIFN_CRYPT_CMD_MODE_CBC		0x0008		/*   CBC */+#define	HIFN_CRYPT_CMD_MODE_CFB		0x0010		/*   CFB */+#define	HIFN_CRYPT_CMD_MODE_OFB		0x0018		/*   OFB */+#define	HIFN_CRYPT_CMD_CLR_CTX		0x0040		/* clear context */+#define	HIFN_CRYPT_CMD_NEW_KEY		0x0800		/* expect new key */+#define	HIFN_CRYPT_CMD_NEW_IV		0x1000		/* expect new iv */++#define	HIFN_CRYPT_CMD_SRCLEN_M		0xc000+#define	HIFN_CRYPT_CMD_SRCLEN_S		14++#define	HIFN_CRYPT_CMD_KSZ_MASK		0x0600		/* AES key size: */+#define	HIFN_CRYPT_CMD_KSZ_128		0x0000		/*   128 bit */+#define	HIFN_CRYPT_CMD_KSZ_192		0x0200		/*   192 bit */+#define	HIFN_CRYPT_CMD_KSZ_256		0x0400		/*   256 bit */++/*+ * Structure to help build up the command data structure.+ */+typedef struct hifn_mac_command {+	volatile u_int16_t masks;+	volatile u_int16_t header_skip;+	volatile u_int16_t source_count;+	volatile u_int16_t reserved;+} hifn_mac_command_t;++#define	HIFN_MAC_CMD_ALG_MASK		0x0001+#define	HIFN_MAC_CMD_ALG_SHA1		0x0000+#define	HIFN_MAC_CMD_ALG_MD5		0x0001+#define	HIFN_MAC_CMD_MODE_MASK		0x000c+#define	HIFN_MAC_CMD_MODE_HMAC		0x0000+#define	HIFN_MAC_CMD_MODE_SSL_MAC	0x0004+#define	HIFN_MAC_CMD_MODE_HASH		0x0008+#define	HIFN_MAC_CMD_MODE_FULL		0x0004+#define	HIFN_MAC_CMD_TRUNC		0x0010+#define	HIFN_MAC_CMD_RESULT		0x0020+#define	HIFN_MAC_CMD_APPEND		0x0040+#define	HIFN_MAC_CMD_SRCLEN_M		0xc000+#define	HIFN_MAC_CMD_SRCLEN_S		14++/*+ * MAC POS IPsec initiates authentication after encryption on encodes+ * and before decryption on decodes.+ */+#define	HIFN_MAC_CMD_POS_IPSEC		0x0200+#define	HIFN_MAC_CMD_NEW_KEY		0x0800++/*+ * The poll frequency and poll scalar defines are unshifted values used+ * to set fields in the DMA Configuration Register.+ */+#ifndef HIFN_POLL_FREQUENCY+#define	HIFN_POLL_FREQUENCY	0x1+#endif++#ifndef HIFN_POLL_SCALAR+#define	HIFN_POLL_SCALAR	0x0+#endif++#define	HIFN_MAX_SEGLEN 	0xffff		/* maximum dma segment len */+#define	HIFN_MAX_DMALEN		0x3ffff		/* maximum dma length */+#endif /* __HIFN_H__ */diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.36/crypto/ocf/hifn/hifn7751var.h--- linux-2.6.36.orig/crypto/ocf/hifn/hifn7751var.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/hifn7751var.h	2010-11-09 20:28:04.832495385 +0100@@ -0,0 +1,369 @@+/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */+/*	$OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $	*/++/*-+ * Invertex AEON / Hifn 7751 driver+ * Copyright (c) 1999 Invertex Inc. All rights reserved.+ * Copyright (c) 1999 Theo de Raadt+ * Copyright (c) 2000-2001 Network Security Technologies, Inc.+ *			http://www.netsec.net+ *+ * Please send any comments, feedback, bug-fixes, or feature requests to+ * software@invertex.com.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored in part by the Defense Advanced Research Projects+ * Agency (DARPA) and Air Force Research Laboratory, Air Force+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.+ *+ */++#ifndef __HIFN7751VAR_H__+#define __HIFN7751VAR_H__++#ifdef __KERNEL__++/*+ * Some configurable values for the driver.  By default command+result+ * descriptor rings are the same size.  The src+dst descriptor rings+ * are sized at 3.5x the number of potential commands.  Slower parts+ * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)+ * src+cmd/result descriptors.  It's not clear that increasing the size+ * of the descriptor rings helps performance significantly as other+ * factors tend to come into play (e.g. copying misaligned packets).+ */+#define	HIFN_D_CMD_RSIZE	24	/* command descriptors */+#define	HIFN_D_SRC_RSIZE	((HIFN_D_CMD_RSIZE * 7) / 2)	/* source descriptors */+#define	HIFN_D_RES_RSIZE	HIFN_D_CMD_RSIZE	/* result descriptors */+#define	HIFN_D_DST_RSIZE	HIFN_D_SRC_RSIZE	/* destination descriptors */++/*+ *  Length values for cryptography+ */+#define HIFN_DES_KEY_LENGTH		8+#define HIFN_3DES_KEY_LENGTH		24+#define HIFN_MAX_CRYPT_KEY_LENGTH	HIFN_3DES_KEY_LENGTH+#define HIFN_IV_LENGTH			8+#define	HIFN_AES_IV_LENGTH		16+#define HIFN_MAX_IV_LENGTH		HIFN_AES_IV_LENGTH++/*+ *  Length values for authentication+ */+#define HIFN_MAC_KEY_LENGTH		64+#define HIFN_MD5_LENGTH			16+#define HIFN_SHA1_LENGTH		20+#define HIFN_MAC_TRUNC_LENGTH		12++#define MAX_SCATTER 64++/*+ * Data structure to hold all 4 rings and any other ring related data.+ */+struct hifn_dma {+	/*+	 *  Descriptor rings.  We add +1 to the size to accomidate the+	 *  jump descriptor.+	 */+	struct hifn_desc	cmdr[HIFN_D_CMD_RSIZE+1];+	struct hifn_desc	srcr[HIFN_D_SRC_RSIZE+1];+	struct hifn_desc	dstr[HIFN_D_DST_RSIZE+1];+	struct hifn_desc	resr[HIFN_D_RES_RSIZE+1];++	struct hifn_command	*hifn_commands[HIFN_D_RES_RSIZE];++	u_char			command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];+	u_char			result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];+	u_int32_t		slop[HIFN_D_CMD_RSIZE];++	u_int64_t		test_src, test_dst;++	/*+	 *  Our current positions for insertion and removal from the desriptor+	 *  rings. +	 */+	int			cmdi, srci, dsti, resi;+	volatile int		cmdu, srcu, dstu, resu;+	int			cmdk, srck, dstk, resk;+};++struct hifn_session {+	int hs_used;+	int hs_mlen;+	u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];+};++#define	HIFN_RING_SYNC(sc, r, i, f)					\+	/* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */++#define	HIFN_CMDR_SYNC(sc, i, f)	HIFN_RING_SYNC((sc), cmdr, (i), (f))+#define	HIFN_RESR_SYNC(sc, i, f)	HIFN_RING_SYNC((sc), resr, (i), (f))+#define	HIFN_SRCR_SYNC(sc, i, f)	HIFN_RING_SYNC((sc), srcr, (i), (f))+#define	HIFN_DSTR_SYNC(sc, i, f)	HIFN_RING_SYNC((sc), dstr, (i), (f))++#define	HIFN_CMD_SYNC(sc, i, f)						\+	/* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */++#define	HIFN_RES_SYNC(sc, i, f)						\+	/* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */++typedef int bus_size_t;++/*+ * Holds data specific to a single HIFN board.+ */+struct hifn_softc {+	softc_device_decl		 sc_dev;++	struct pci_dev		*sc_pcidev;	/* PCI device pointer */+	spinlock_t		sc_mtx;		/* per-instance lock */++	int			sc_num;		/* for multiple devs */++	ocf_iomem_t		sc_bar0;+	bus_size_t		sc_bar0_lastreg;/* bar0 last reg written */+	ocf_iomem_t		sc_bar1;+	bus_size_t		sc_bar1_lastreg;/* bar1 last reg written */++	int			sc_irq;++	u_int32_t		sc_dmaier;+	u_int32_t		sc_drammodel;	/* 1=dram, 0=sram */+	u_int32_t		sc_pllconfig;	/* 7954/7955/7956 PLL config */++	struct hifn_dma		*sc_dma;+	dma_addr_t		sc_dma_physaddr;/* physical address of sc_dma */++	int			sc_dmansegs;+	int32_t			sc_cid;+	int			sc_maxses;+	int			sc_nsessions;+	struct hifn_session	*sc_sessions;+	int			sc_ramsize;+	int			sc_flags;+#define	HIFN_HAS_RNG		0x1	/* includes random number generator */+#define	HIFN_HAS_PUBLIC		0x2	/* includes public key support */+#define	HIFN_HAS_AES		0x4	/* includes AES support */+#define	HIFN_IS_7811		0x8	/* Hifn 7811 part */+#define	HIFN_IS_7956		0x10	/* Hifn 7956/7955 don't have SDRAM */++	struct timer_list	sc_tickto;	/* for managing DMA */++	int			sc_rngfirst;+	int			sc_rnghz;	/* RNG polling frequency */++	int			sc_c_busy;	/* command ring busy */+	int			sc_s_busy;	/* source data ring busy */+	int			sc_d_busy;	/* destination data ring busy */+	int			sc_r_busy;	/* result ring busy */+	int			sc_active;	/* for initial countdown */+	int			sc_needwakeup;	/* ops q'd wating on resources */+	int			sc_curbatch;	/* # ops submitted w/o int */+	int			sc_suspended;+#ifdef HIFN_VULCANDEV+	struct cdev            *sc_pkdev;+#endif+};++#define	HIFN_LOCK(_sc)		spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)+#define	HIFN_UNLOCK(_sc)	spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)++/*+ *  hifn_command_t+ *+ *  This is the control structure used to pass commands to hifn_encrypt().+ *+ *  flags+ *  -----+ *  Flags is the bitwise "or" values for command configuration.  A single+ *  encrypt direction needs to be set:+ *+ *	HIFN_ENCODE or HIFN_DECODE+ *+ *  To use cryptography, a single crypto algorithm must be included:+ *+ *	HIFN_CRYPT_3DES or HIFN_CRYPT_DES+ *+ *  To use authentication is used, a single MAC algorithm must be included:+ *+ *	HIFN_MAC_MD5 or HIFN_MAC_SHA1+ *+ *  By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.+ *  If the value below is set, hash values are truncated or assumed+ *  truncated to 12 bytes:+ *+ *	HIFN_MAC_TRUNC+ *+ *  Keys for encryption and authentication can be sent as part of a command,+ *  or the last key value used with a particular session can be retrieved+ *  and used again if either of these flags are not specified.+ *+ *	HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY+ *+ *  session_num+ *  -----------+ *  A number between 0 and 2048 (for DRAM models) or a number between + *  0 and 768 (for SRAM models).  Those who don't want to use session+ *  numbers should leave value at zero and send a new crypt key and/or+ *  new MAC key on every command.  If you use session numbers and+ *  don't send a key with a command, the last key sent for that same+ *  session number will be used.+ *+ *  Warning:  Using session numbers and multiboard at the same time+ *            is currently broken.+ *+ *  mbuf+ *  ----+ *  Either fill in the mbuf pointer and npa=0 or+ *	 fill packp[] and packl[] and set npa to > 0+ * + *  mac_header_skip+ *  ---------------+ *  The number of bytes of the source_buf that are skipped over before+ *  authentication begins.  This must be a number between 0 and 2^16-1+ *  and can be used by IPsec implementers to skip over IP headers.+ *  *** Value ignored if authentication not used ***+ *+ *  crypt_header_skip+ *  -----------------+ *  The number of bytes of the source_buf that are skipped over before+ *  the cryptographic operation begins.  This must be a number between 0+ *  and 2^16-1.  For IPsec, this number will always be 8 bytes larger+ *  than the auth_header_skip (to skip over the ESP header).+ *  *** Value ignored if cryptography not used ***+ *+ */+struct hifn_operand {+	union {+		struct sk_buff *skb;+		struct uio *io;+		unsigned char *buf;+	} u;+	void		*map;+	bus_size_t	mapsize;+	int		nsegs;+	struct {+	    dma_addr_t  ds_addr;+	    int         ds_len;+	} segs[MAX_SCATTER];+};++struct hifn_command {+	u_int16_t session_num;+	u_int16_t base_masks, cry_masks, mac_masks;+	u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];+	int cklen;+	int sloplen, slopidx;++	struct hifn_operand src;+	struct hifn_operand dst;++	struct hifn_softc *softc;+	struct cryptop *crp;+	struct cryptodesc *enccrd, *maccrd;+};++#define	src_skb		src.u.skb+#define	src_io		src.u.io+#define	src_map		src.map+#define	src_mapsize	src.mapsize+#define	src_segs	src.segs+#define	src_nsegs	src.nsegs+#define	src_buf		src.u.buf++#define	dst_skb		dst.u.skb+#define	dst_io		dst.u.io+#define	dst_map		dst.map+#define	dst_mapsize	dst.mapsize+#define	dst_segs	dst.segs+#define	dst_nsegs	dst.nsegs+#define	dst_buf		dst.u.buf++/*+ *  Return values for hifn_crypto()+ */+#define HIFN_CRYPTO_SUCCESS	0+#define HIFN_CRYPTO_BAD_INPUT	(-1)+#define HIFN_CRYPTO_RINGS_FULL	(-2)++/**************************************************************************+ *+ *  Function:  hifn_crypto+ *+ *  Purpose:   Called by external drivers to begin an encryption on the+ *             HIFN board.+ *+ *  Blocking/Non-blocking Issues+ *  ============================+ *  The driver cannot block in hifn_crypto (no calls to tsleep) currently.+ *  hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough+ *  room in any of the rings for the request to proceed.+ *+ *  Return Values+ *  =============+ *  0 for success, negative values on error+ *+ *  Defines for negative error codes are:+ *  + *    HIFN_CRYPTO_BAD_INPUT  :  The passed in command had invalid settings.+ *    HIFN_CRYPTO_RINGS_FULL :  All DMA rings were full and non-blocking+ *                              behaviour was requested.+ *+ *************************************************************************/++/*+ * Convert back and forth from 'sid' to 'card' and 'session'+ */+#define HIFN_CARD(sid)		(((sid) & 0xf0000000) >> 28)+#define HIFN_SESSION(sid)	((sid) & 0x000007ff)+#define HIFN_SID(crd,ses)	(((crd) << 28) | ((ses) & 0x7ff))++#endif /* _KERNEL */++struct hifn_stats {+	u_int64_t hst_ibytes;+	u_int64_t hst_obytes;+	u_int32_t hst_ipackets;+	u_int32_t hst_opackets;+	u_int32_t hst_invalid;+	u_int32_t hst_nomem;		/* malloc or one of hst_nomem_* */+	u_int32_t hst_abort;+	u_int32_t hst_noirq;		/* IRQ for no reason */+	u_int32_t hst_totbatch;		/* ops submitted w/o interrupt */+	u_int32_t hst_maxbatch;		/* max ops submitted together */+	u_int32_t hst_unaligned;	/* unaligned src caused copy */+	/*+	 * The following divides hst_nomem into more specific buckets.+	 */+	u_int32_t hst_nomem_map;	/* bus_dmamap_create failed */+	u_int32_t hst_nomem_load;	/* bus_dmamap_load_* failed */+	u_int32_t hst_nomem_mbuf;	/* MGET* failed */+	u_int32_t hst_nomem_mcl;	/* MCLGET* failed */+	u_int32_t hst_nomem_cr;		/* out of command/result descriptor */+	u_int32_t hst_nomem_sd;		/* out of src/dst descriptors */+};++#endif /* __HIFN7751VAR_H__ */diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.36/crypto/ocf/hifn/hifnHIPP.c--- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPP.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/hifnHIPP.c	2010-11-09 20:28:04.881244876 +0100@@ -0,0 +1,420 @@+/*-+ * Driver for Hifn HIPP-I/II chipset+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *   notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *   notice, this list of conditions and the following disclaimer in the+ *   documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *   derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored by Hifn Inc.+ *+ */++/*+ * Driver for various Hifn encryption processors.+ */+#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/wait.h>+#include <linux/sched.h>+#include <linux/pci.h>+#include <linux/delay.h>+#include <linux/interrupt.h>+#include <linux/spinlock.h>+#include <linux/random.h>+#include <linux/version.h>+#include <linux/skbuff.h>+#include <linux/uio.h>+#include <linux/sysfs.h>+#include <linux/miscdevice.h>+#include <asm/io.h>++#include <cryptodev.h>++#include "hifnHIPPreg.h"+#include "hifnHIPPvar.h"++#if 1+#define	DPRINTF(a...)	if (hipp_debug) { \+							printk("%s: ", sc ? \+								device_get_nameunit(sc->sc_dev) : "hifn"); \+							printk(a); \+						} else+#else+#define	DPRINTF(a...)+#endif++typedef int bus_size_t;++static inline int+pci_get_revid(struct pci_dev *dev)+{+	u8 rid = 0;+	pci_read_config_byte(dev, PCI_REVISION_ID, &rid);+	return rid;+}++#define debug hipp_debug+int hipp_debug = 0;+module_param(hipp_debug, int, 0644);+MODULE_PARM_DESC(hipp_debug, "Enable debug");++int hipp_maxbatch = 1;+module_param(hipp_maxbatch, int, 0644);+MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");++static	int  hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);+static	void hipp_remove(struct pci_dev *dev);+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+static irqreturn_t hipp_intr(int irq, void *arg);+#else+static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);+#endif++static int hipp_num_chips = 0;+static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];++static	int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);+static	int hipp_freesession(device_t, u_int64_t);+static	int hipp_process(device_t, struct cryptop *, int);++static device_method_t hipp_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	hipp_newsession),+	DEVMETHOD(cryptodev_freesession,hipp_freesession),+	DEVMETHOD(cryptodev_process,	hipp_process),+};++static __inline u_int32_t+READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)+{+	u_int32_t v = readl(sc->sc_bar[barno] + reg);+	//sc->sc_bar0_lastreg = (bus_size_t) -1;+	return (v);+}+static __inline void+WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)+{+	writel(val, sc->sc_bar[barno] + reg);+}++#define READ_REG_0(sc, reg)         READ_REG(sc, 0, reg)+#define WRITE_REG_0(sc, reg, val)   WRITE_REG(sc,0, reg, val)+#define READ_REG_1(sc, reg)         READ_REG(sc, 1, reg)+#define WRITE_REG_1(sc, reg, val)   WRITE_REG(sc,1, reg, val)++static int+hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)+{+	return EINVAL;+}++static int+hipp_freesession(device_t dev, u_int64_t tid)+{+	return EINVAL;+}++static int+hipp_process(device_t dev, struct cryptop *crp, int hint)+{+	return EINVAL;+}++static const char*+hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)+{+	char *n = NULL;++	switch (pci_get_vendor(sc->sc_pcidev)) {+	case PCI_VENDOR_HIFN:+		switch (pci_get_device(sc->sc_pcidev)) {+		case PCI_PRODUCT_HIFN_7855:	n = "Hifn 7855";+		case PCI_PRODUCT_HIFN_8155:	n = "Hifn 8155";+		case PCI_PRODUCT_HIFN_6500:	n = "Hifn 6500";+		}+	}++	if(n==NULL) {+		snprintf(buf, blen, "VID=%02x,PID=%02x",+			 pci_get_vendor(sc->sc_pcidev),+			 pci_get_device(sc->sc_pcidev));+	} else {+		buf[0]='\0';+		strncat(buf, n, blen);+	}+	return buf;+}++struct hipp_fs_entry {+	struct attribute attr;+	/* other stuff */+};+++static ssize_t+cryptoid_show(struct device *dev,+	      struct device_attribute *attr,+	      char *buf)						+{								+	struct hipp_softc *sc;					++	sc = pci_get_drvdata(to_pci_dev (dev));+	return sprintf (buf, "%d\n", sc->sc_cid);+}++struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);++/*+ * Attach an interface that successfully probed.+ */+static int+hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)+{+	struct hipp_softc *sc = NULL;+	int i;+	//char rbase;+	//u_int16_t ena;+	int rev;+	//int rseg;+	int rc;++	DPRINTF("%s()\n", __FUNCTION__);++	if (pci_enable_device(dev) < 0)+		return(-ENODEV);++	if (pci_set_mwi(dev))+		return(-ENODEV);++	if (!dev->irq) {+		printk("hifn: found device with no IRQ assigned. check BIOS settings!");+		pci_disable_device(dev);+		return(-ENODEV);+	}++	sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);+	if (!sc)+		return(-ENOMEM);+	memset(sc, 0, sizeof(*sc));++	softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);++	sc->sc_pcidev = dev;+	sc->sc_irq = -1;+	sc->sc_cid = -1;+	sc->sc_num = hipp_num_chips++;++	if (sc->sc_num < HIPP_MAX_CHIPS)+		hipp_chip_idx[sc->sc_num] = sc;++	pci_set_drvdata(sc->sc_pcidev, sc);++	spin_lock_init(&sc->sc_mtx);++	/*+	 * Setup PCI resources.+	 * The READ_REG_0, WRITE_REG_0, READ_REG_1,+	 * and WRITE_REG_1 macros throughout the driver are used+	 * to permit better debugging.+	 */+	for(i=0; i<4; i++) {+		unsigned long mem_start, mem_len;+		mem_start = pci_resource_start(sc->sc_pcidev, i);+		mem_len   = pci_resource_len(sc->sc_pcidev, i);+		sc->sc_barphy[i] = (caddr_t)mem_start;+		sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);+		if (!sc->sc_bar[i]) {+			device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);+			goto fail;+		}+	}++	//hipp_reset_board(sc, 0);+	pci_set_master(sc->sc_pcidev);++	/*+	 * Arrange the interrupt line.+	 */+	rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);+	if (rc) {+		device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);+		goto fail;+	}+	sc->sc_irq = dev->irq;++	rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;++	{+		char b[32];+		device_printf(sc->sc_dev, "%s, rev %u",+			      hipp_partname(sc, b, sizeof(b)), rev);+	}++#if 0+	if (sc->sc_flags & HIFN_IS_7956)+		printf(", pll=0x%x<%s clk, %ux mult>",+			sc->sc_pllconfig,+			sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",+			2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));+#endif+	printf("\n");++	sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);+	if (sc->sc_cid < 0) {+		device_printf(sc->sc_dev, "could not get crypto driver id\n");+		goto fail;+	}++#if 0 /* cannot work with a non-GPL module */+	/* make a sysfs entry to let the world know what entry we got */+	sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);+#endif++#if 0+	init_timer(&sc->sc_tickto);+	sc->sc_tickto.function = hifn_tick;+	sc->sc_tickto.data = (unsigned long) sc->sc_num;+	mod_timer(&sc->sc_tickto, jiffies + HZ);+#endif++#if 0 /* no code here yet ?? */+	crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);+#endif++	return (0);++fail:+	if (sc->sc_cid >= 0)+		crypto_unregister_all(sc->sc_cid);+	if (sc->sc_irq != -1)+		free_irq(sc->sc_irq, sc);+	+#if 0+	if (sc->sc_dma) {+		/* Turn off DMA polling */+		WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+			    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);+		+		pci_free_consistent(sc->sc_pcidev,+				    sizeof(*sc->sc_dma),+				    sc->sc_dma, sc->sc_dma_physaddr);+	}+#endif+	kfree(sc);+	return (-ENXIO);+}++/*+ * Detach an interface that successfully probed.+ */+static void+hipp_remove(struct pci_dev *dev)+{+	struct hipp_softc *sc = pci_get_drvdata(dev);+	unsigned long l_flags;++	DPRINTF("%s()\n", __FUNCTION__);++	/* disable interrupts */+	HIPP_LOCK(sc);++#if 0+	WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);+	HIFN_UNLOCK(sc);++	/*XXX other resources */+	del_timer_sync(&sc->sc_tickto);++	/* Turn off DMA polling */+	WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |+	    HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);+#endif++	crypto_unregister_all(sc->sc_cid);++	free_irq(sc->sc_irq, sc);++#if 0+	pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),+                sc->sc_dma, sc->sc_dma_physaddr);+#endif+}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+static irqreturn_t hipp_intr(int irq, void *arg)+#else+static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)+#endif+{+	struct hipp_softc *sc = arg;++	sc = sc; /* shut up compiler */++	return IRQ_HANDLED;+}++static struct pci_device_id hipp_pci_tbl[] = {+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+};+MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);++static struct pci_driver hipp_driver = {+	.name         = "hipp",+	.id_table     = hipp_pci_tbl,+	.probe        =	hipp_probe,+	.remove       = hipp_remove,+	/* add PM stuff here one day */+};++static int __init hipp_init (void)+{+	struct hipp_softc *sc = NULL;+	int rc;++	DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);++	rc = pci_register_driver(&hipp_driver);+	pci_register_driver_compat(&hipp_driver, rc);++	return rc;+}++static void __exit hipp_exit (void)+{+	pci_unregister_driver(&hipp_driver);+}++module_init(hipp_init);+module_exit(hipp_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");+MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.36/crypto/ocf/hifn/hifnHIPPreg.h--- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPreg.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/hifnHIPPreg.h	2010-11-09 20:28:04.922495399 +0100@@ -0,0 +1,46 @@+/*-+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored by Hifn inc.+ *+ */++#ifndef __HIFNHIPP_H__+#define	__HIFNHIPP_H__++/*+ * PCI vendor and device identifiers+ */+#define	PCI_VENDOR_HIFN		0x13a3		/* Hifn */+#define	PCI_PRODUCT_HIFN_6500	0x0006		/* 6500 */+#define	PCI_PRODUCT_HIFN_7855	0x001f		/* 7855 */+#define	PCI_PRODUCT_HIFN_8155	0x999		/* XXX 8155 */++#define HIPP_1_REVID            0x01 /* BOGUS */++#endif /* __HIPP_H__ */diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.36/crypto/ocf/hifn/hifnHIPPvar.h--- linux-2.6.36.orig/crypto/ocf/hifn/hifnHIPPvar.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/hifnHIPPvar.h	2010-11-09 20:28:04.964807923 +0100@@ -0,0 +1,93 @@+/*+ * Hifn HIPP-I/HIPP-II (7855/8155) driver.+ * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> * + *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * Effort sponsored by Hifn inc.+ *+ */++#ifndef __HIFNHIPPVAR_H__+#define __HIFNHIPPVAR_H__++#define HIPP_MAX_CHIPS 8++/*+ * Holds data specific to a single Hifn HIPP-I board.+ */+struct hipp_softc {+	softc_device_decl		 sc_dev;++	struct pci_dev		*sc_pcidev;	/* device backpointer */+	ocf_iomem_t             sc_bar[5];+	caddr_t		        sc_barphy[5];   /* physical address */+	int			sc_num;		/* for multiple devs */+	spinlock_t		sc_mtx;		/* per-instance lock */+	int32_t			sc_cid;+	int			sc_irq;++#if 0++	u_int32_t		sc_dmaier;+	u_int32_t		sc_drammodel;	/* 1=dram, 0=sram */+	u_int32_t		sc_pllconfig;	/* 7954/7955/7956 PLL config */++	struct hifn_dma		*sc_dma;+	dma_addr_t		sc_dma_physaddr;/* physical address of sc_dma */++	int			sc_dmansegs;+	int			sc_maxses;+	int			sc_nsessions;+	struct hifn_session	*sc_sessions;+	int			sc_ramsize;+	int			sc_flags;+#define	HIFN_HAS_RNG		0x1	/* includes random number generator */+#define	HIFN_HAS_PUBLIC		0x2	/* includes public key support */+#define	HIFN_HAS_AES		0x4	/* includes AES support */+#define	HIFN_IS_7811		0x8	/* Hifn 7811 part */+#define	HIFN_IS_7956		0x10	/* Hifn 7956/7955 don't have SDRAM */++	struct timer_list	sc_tickto;	/* for managing DMA */++	int			sc_rngfirst;+	int			sc_rnghz;	/* RNG polling frequency */++	int			sc_c_busy;	/* command ring busy */+	int			sc_s_busy;	/* source data ring busy */+	int			sc_d_busy;	/* destination data ring busy */+	int			sc_r_busy;	/* result ring busy */+	int			sc_active;	/* for initial countdown */+	int			sc_needwakeup;	/* ops q'd wating on resources */+	int			sc_curbatch;	/* # ops submitted w/o int */+	int			sc_suspended;+	struct miscdevice       sc_miscdev;+#endif+};++#define	HIPP_LOCK(_sc)		spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)+#define	HIPP_UNLOCK(_sc)	spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)++#endif /* __HIFNHIPPVAR_H__ */diff -Nur linux-2.6.36.orig/crypto/ocf/hifn/Makefile linux-2.6.36/crypto/ocf/hifn/Makefile--- linux-2.6.36.orig/crypto/ocf/hifn/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/hifn/Makefile	2010-11-09 20:28:05.002825564 +0100@@ -0,0 +1,13 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_HIFN)     += hifn7751.o+obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.36/crypto/ocf/ixp4xx/ixp4xx.c--- linux-2.6.36.orig/crypto/ocf/ixp4xx/ixp4xx.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ixp4xx/ixp4xx.c	2010-11-09 20:28:05.051258556 +0100@@ -0,0 +1,1324 @@+/*+ * An OCF module that uses Intels IXP CryptACC API to do the crypto.+ * This driver requires the IXP400 Access Library that is available+ * from Intel in order to operate (or compile).+ *+ * Written by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this product+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/sched.h>+#include <linux/wait.h>+#include <linux/crypto.h>+#include <linux/interrupt.h>+#include <asm/scatterlist.h>++#include <IxTypes.h>+#include <IxOsBuffMgt.h>+#include <IxNpeDl.h>+#include <IxCryptoAcc.h>+#include <IxQMgr.h>+#include <IxOsServices.h>+#include <IxOsCacheMMU.h>++#include <cryptodev.h>+#include <uio.h>++#ifndef IX_MBUF_PRIV+#define IX_MBUF_PRIV(x) ((x)->priv)+#endif++struct ixp_data;++struct ixp_q {+	struct list_head	 ixp_q_list;+	struct ixp_data		*ixp_q_data;+	struct cryptop		*ixp_q_crp;+	struct cryptodesc	*ixp_q_ccrd;+	struct cryptodesc	*ixp_q_acrd;+	IX_MBUF				 ixp_q_mbuf;+	UINT8				*ixp_hash_dest; /* Location for hash in client buffer */+	UINT8				*ixp_hash_src; /* Location of hash in internal buffer */+	unsigned char		 ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];+	unsigned char		*ixp_q_iv;+};++struct ixp_data {+	int					 ixp_registered;	/* is the context registered */+	int					 ixp_crd_flags;		/* detect direction changes */++	int					 ixp_cipher_alg;+	int					 ixp_auth_alg;++	UINT32				 ixp_ctx_id;+	UINT32				 ixp_hash_key_id;	/* used when hashing */+	IxCryptoAccCtx		 ixp_ctx;+	IX_MBUF				 ixp_pri_mbuf;+	IX_MBUF				 ixp_sec_mbuf;++	struct work_struct   ixp_pending_work;+	struct work_struct   ixp_registration_work;+	struct list_head	 ixp_q;				/* unprocessed requests */+};++#ifdef __ixp46X++#define	MAX_IOP_SIZE	64	/* words */+#define	MAX_OOP_SIZE	128++#define	MAX_PARAMS		3++struct ixp_pkq {+	struct list_head			 pkq_list;+	struct cryptkop				*pkq_krp;++	IxCryptoAccPkeEauInOperands	 pkq_op;+	IxCryptoAccPkeEauOpResult	 pkq_result;++	UINT32						 pkq_ibuf0[MAX_IOP_SIZE];+	UINT32						 pkq_ibuf1[MAX_IOP_SIZE];+	UINT32						 pkq_ibuf2[MAX_IOP_SIZE];+	UINT32						 pkq_obuf[MAX_OOP_SIZE];+};++static LIST_HEAD(ixp_pkq); /* current PK wait list */+static struct ixp_pkq *ixp_pk_cur;+static spinlock_t ixp_pkq_lock;++#endif /* __ixp46X */++static int ixp_blocked = 0;++static int32_t			 ixp_id = -1;+static struct ixp_data **ixp_sessions = NULL;+static u_int32_t		 ixp_sesnum = 0;++static int ixp_process(device_t, struct cryptop *, int);+static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);+static int ixp_freesession(device_t, u_int64_t);+#ifdef __ixp46X+static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);+#endif++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)+static kmem_cache_t *qcache;+#else+static struct kmem_cache *qcache;+#endif++#define debug ixp_debug+static int ixp_debug = 0;+module_param(ixp_debug, int, 0644);+MODULE_PARM_DESC(ixp_debug, "Enable debug");++static int ixp_init_crypto = 1;+module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */+MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");++static void ixp_process_pending(void *arg);+static void ixp_registration(void *arg);+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void ixp_process_pending_wq(struct work_struct *work);+static void ixp_registration_wq(struct work_struct *work);+#endif++/*+ * dummy device structure+ */++static struct {+	softc_device_decl	sc_dev;+} ixpdev;++static device_method_t ixp_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	ixp_newsession),+	DEVMETHOD(cryptodev_freesession,ixp_freesession),+	DEVMETHOD(cryptodev_process,	ixp_process),+#ifdef __ixp46X+	DEVMETHOD(cryptodev_kprocess,	ixp_kprocess),+#endif+};++/*+ * Generate a new software session.+ */+static int+ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)+{+	struct ixp_data *ixp;+	u_int32_t i;+#define AUTH_LEN(cri, def) \+	(cri->cri_mlen ? cri->cri_mlen : (def))++	dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);+	if (sid == NULL || cri == NULL) {+		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	if (ixp_sessions) {+		for (i = 1; i < ixp_sesnum; i++)+			if (ixp_sessions[i] == NULL)+				break;+	} else+		i = 1;		/* NB: to silence compiler warning */++	if (ixp_sessions == NULL || i == ixp_sesnum) {+		struct ixp_data **ixpd;++		if (ixp_sessions == NULL) {+			i = 1; /* We leave ixp_sessions[0] empty */+			ixp_sesnum = CRYPTO_SW_SESSIONS;+		} else+			ixp_sesnum *= 2;++		ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);+		if (ixpd == NULL) {+			/* Reset session number */+			if (ixp_sesnum == CRYPTO_SW_SESSIONS)+				ixp_sesnum = 0;+			else+				ixp_sesnum /= 2;+			dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);+			return ENOBUFS;+		}+		memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));++		/* Copy existing sessions */+		if (ixp_sessions) {+			memcpy(ixpd, ixp_sessions,+			    (ixp_sesnum / 2) * sizeof(struct ixp_data *));+			kfree(ixp_sessions);+		}++		ixp_sessions = ixpd;+	}++	ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),+			SLAB_ATOMIC);+	if (ixp_sessions[i] == NULL) {+		ixp_freesession(NULL, i);+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return ENOBUFS;+	}++	*sid = i;++	ixp = ixp_sessions[i];+	memset(ixp, 0, sizeof(*ixp));++	ixp->ixp_cipher_alg = -1;+	ixp->ixp_auth_alg = -1;+	ixp->ixp_ctx_id = -1;+	INIT_LIST_HEAD(&ixp->ixp_q);++	ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;++	while (cri) {+		switch (cri->cri_alg) {+		case CRYPTO_DES_CBC:+			ixp->ixp_cipher_alg = cri->cri_alg;+			ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;+			ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;+			ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;+			ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;+			ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =+						IX_CRYPTO_ACC_DES_IV_64;+			memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,+					cri->cri_key, (cri->cri_klen + 7) / 8);+			break;++		case CRYPTO_3DES_CBC:+			ixp->ixp_cipher_alg = cri->cri_alg;+			ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;+			ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;+			ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;+			ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;+			ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =+						IX_CRYPTO_ACC_DES_IV_64;+			memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,+					cri->cri_key, (cri->cri_klen + 7) / 8);+			break;++		case CRYPTO_RIJNDAEL128_CBC:+			ixp->ixp_cipher_alg = cri->cri_alg;+			ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;+			ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;+			ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;+			ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;+			ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;+			memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,+					cri->cri_key, (cri->cri_klen + 7) / 8);+			break;++		case CRYPTO_MD5:+		case CRYPTO_MD5_HMAC:+			ixp->ixp_auth_alg = cri->cri_alg;+			ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;+			ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);+			ixp->ixp_ctx.authCtx.aadLen = 0;+			/* Only MD5_HMAC needs a key */+			if (cri->cri_alg == CRYPTO_MD5_HMAC) {+				ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;+				if (ixp->ixp_ctx.authCtx.authKeyLen >+						sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {+					printk(+						"ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",+							cri->cri_klen);+					ixp_freesession(NULL, i);+					return EINVAL;+				}+				memcpy(ixp->ixp_ctx.authCtx.key.authKey,+						cri->cri_key, (cri->cri_klen + 7) / 8);+			}+			break;++		case CRYPTO_SHA1:+		case CRYPTO_SHA1_HMAC:+			ixp->ixp_auth_alg = cri->cri_alg;+			ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;+			ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);+			ixp->ixp_ctx.authCtx.aadLen = 0;+			/* Only SHA1_HMAC needs a key */+			if (cri->cri_alg == CRYPTO_SHA1_HMAC) {+				ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;+				if (ixp->ixp_ctx.authCtx.authKeyLen >+						sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {+					printk(+						"ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",+							cri->cri_klen);+					ixp_freesession(NULL, i);+					return EINVAL;+				}+				memcpy(ixp->ixp_ctx.authCtx.key.authKey,+						cri->cri_key, (cri->cri_klen + 7) / 8);+			}+			break;++		default:+			printk("ixp: unknown algo 0x%x\n", cri->cri_alg);+			ixp_freesession(NULL, i);+			return EINVAL;+		}+		cri = cri->cri_next;+	}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+	INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);+	INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);+#else+	INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);+	INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);+#endif++	return 0;+}+++/*+ * Free a session.+ */+static int+ixp_freesession(device_t dev, u_int64_t tid)+{+	u_int32_t sid = CRYPTO_SESID2LID(tid);++	dprintk("%s()\n", __FUNCTION__);+	if (sid > ixp_sesnum || ixp_sessions == NULL ||+			ixp_sessions[sid] == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	/* Silently accept and return */+	if (sid == 0)+		return 0;++	if (ixp_sessions[sid]) {+		if (ixp_sessions[sid]->ixp_ctx_id != -1) {+			ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);+			ixp_sessions[sid]->ixp_ctx_id = -1;+		}+		kfree(ixp_sessions[sid]);+	}+	ixp_sessions[sid] = NULL;+	if (ixp_blocked) {+		ixp_blocked = 0;+		crypto_unblock(ixp_id, CRYPTO_SYMQ);+	}+	return 0;+}+++/*+ * callback for when hash processing is complete+ */++static void+ixp_hash_perform_cb(+	UINT32 hash_key_id,+	IX_MBUF *bufp,+	IxCryptoAccStatus status)+{+	struct ixp_q *q;++	dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);++	if (bufp == NULL) {+		printk("ixp: NULL buf in %s\n", __FUNCTION__);+		return;+	}++	q = IX_MBUF_PRIV(bufp);+	if (q == NULL) {+		printk("ixp: NULL priv in %s\n", __FUNCTION__);+		return;+	}++	if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {+		/* On success, need to copy hash back into original client buffer */+		memcpy(q->ixp_hash_dest, q->ixp_hash_src,+				(q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?+					SHA1_HASH_LEN : MD5_HASH_LEN);+	}+	else {+		printk("ixp: hash perform failed status=%d\n", status);+		q->ixp_q_crp->crp_etype = EINVAL;+	}++	/* Free internal buffer used for hashing */+	kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));++	crypto_done(q->ixp_q_crp);+	kmem_cache_free(qcache, q);+}++/*+ * setup a request and perform it+ */+static void+ixp_q_process(struct ixp_q *q)+{+	IxCryptoAccStatus status;+	struct ixp_data *ixp = q->ixp_q_data;+	int auth_off = 0;+	int auth_len = 0;+	int crypt_off = 0;+	int crypt_len = 0;+	int icv_off = 0;+	char *crypt_func;++	dprintk("%s(%p)\n", __FUNCTION__, q);++	if (q->ixp_q_ccrd) {+		if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {+			q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;+		} else {+			q->ixp_q_iv = q->ixp_q_iv_data;+			crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,+					q->ixp_q_ccrd->crd_inject,+					ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,+					(caddr_t) q->ixp_q_iv);+		}++		if (q->ixp_q_acrd) {+			auth_off = q->ixp_q_acrd->crd_skip;+			auth_len = q->ixp_q_acrd->crd_len;+			icv_off  = q->ixp_q_acrd->crd_inject;+		}++		crypt_off = q->ixp_q_ccrd->crd_skip;+		crypt_len = q->ixp_q_ccrd->crd_len;+	} else { /* if (q->ixp_q_acrd) */+		auth_off = q->ixp_q_acrd->crd_skip;+		auth_len = q->ixp_q_acrd->crd_len;+		icv_off  = q->ixp_q_acrd->crd_inject;+	}++	if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {+		struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;+		if (skb_shinfo(skb)->nr_frags) {+			/*+			 * DAVIDM fix this limitation one day by using+			 * a buffer pool and chaining,  it is not currently+			 * needed for current user/kernel space acceleration+			 */+			printk("ixp: Cannot handle fragmented skb's yet !\n");+			q->ixp_q_crp->crp_etype = ENOENT;+			goto done;+		}+		IX_MBUF_MLEN(&q->ixp_q_mbuf) =+				IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =  skb->len;+		IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;+	} else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {+		struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;+		if (uiop->uio_iovcnt != 1) {+			/*+			 * DAVIDM fix this limitation one day by using+			 * a buffer pool and chaining,  it is not currently+			 * needed for current user/kernel space acceleration+			 */+			printk("ixp: Cannot handle more than 1 iovec yet !\n");+			q->ixp_q_crp->crp_etype = ENOENT;+			goto done;+		}+		IX_MBUF_MLEN(&q->ixp_q_mbuf) =+				IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;+		IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;+	} else /* contig buffer */ {+		IX_MBUF_MLEN(&q->ixp_q_mbuf)  =+				IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;+		IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;+	}++	IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;++	if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {+		/*+		 * For SHA1 and MD5 hash, need to create an internal buffer that is big+		 * enough to hold the original data + the appropriate padding for the+		 * hash algorithm.+		 */+		UINT8 *tbuf = NULL;++		IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =+			((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;+		tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);+		+		if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {+			printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",+					IX_MBUF_MLEN(&q->ixp_q_mbuf));+			q->ixp_q_crp->crp_etype = ENOMEM;+			goto done;+		}+		memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);++		/* Set location in client buffer to copy hash into */+		q->ixp_hash_dest =+			&(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];++		IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;++		/* Set location in internal buffer for where hash starts */+		q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];++		crypt_func = "ixCryptoAccHashPerform";+		status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,+				&q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,+				&ixp->ixp_hash_key_id);+	}+	else {+		crypt_func = "ixCryptoAccAuthCryptPerform";+		status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,+			NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,+			q->ixp_q_iv);+	}++	if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)+		return;++	if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {+		q->ixp_q_crp->crp_etype = ENOMEM;+		goto done;+	}++	printk("ixp: %s failed %u\n", crypt_func, status);+	q->ixp_q_crp->crp_etype = EINVAL;++done:+	crypto_done(q->ixp_q_crp);+	kmem_cache_free(qcache, q);+}+++/*+ * because we cannot process the Q from the Register callback+ * we do it here on a task Q.+ */++static void+ixp_process_pending(void *arg)+{+	struct ixp_data *ixp = arg;+	struct ixp_q *q = NULL;++	dprintk("%s(%p)\n", __FUNCTION__, arg);++	if (!ixp)+		return;++	while (!list_empty(&ixp->ixp_q)) {+		q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);+		list_del(&q->ixp_q_list);+		ixp_q_process(q);+	}+}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void+ixp_process_pending_wq(struct work_struct *work)+{+	struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);+	ixp_process_pending(ixp);+}+#endif++/*+ * callback for when context registration is complete+ */++static void+ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)+{+	int i;+	struct ixp_data *ixp;+	struct ixp_q *q;++	dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);++	/*+	 * free any buffer passed in to this routine+	 */+	if (bufp) {+		IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;+		kfree(IX_MBUF_MDATA(bufp));+		IX_MBUF_MDATA(bufp) = NULL;+	}++	for (i = 0; i < ixp_sesnum; i++) {+		ixp = ixp_sessions[i];+		if (ixp && ixp->ixp_ctx_id == ctx_id)+			break;+	}+	if (i >= ixp_sesnum) {+		printk("ixp: invalid context id %d\n", ctx_id);+		return;+	}++	if (IX_CRYPTO_ACC_STATUS_WAIT == status) {+		/* this is normal to free the first of two buffers */+		dprintk("ixp: register not finished yet.\n");+		return;+	}++	if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {+		printk("ixp: register failed 0x%x\n", status);+		while (!list_empty(&ixp->ixp_q)) {+			q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);+			list_del(&q->ixp_q_list);+			q->ixp_q_crp->crp_etype = EINVAL;+			crypto_done(q->ixp_q_crp);+			kmem_cache_free(qcache, q);+		}+		return;+	}++	/*+	 * we are now registered,  we cannot start processing the Q here+	 * or we get strange errors with AES (DES/3DES seem to be ok).+	 */+	ixp->ixp_registered = 1;+	schedule_work(&ixp->ixp_pending_work);+}+++/*+ * callback for when data processing is complete+ */++static void+ixp_perform_cb(+	UINT32 ctx_id,+	IX_MBUF *sbufp,+	IX_MBUF *dbufp,+	IxCryptoAccStatus status)+{+	struct ixp_q *q;++	dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,+			dbufp, status);++	if (sbufp == NULL) {+		printk("ixp: NULL sbuf in ixp_perform_cb\n");+		return;+	}++	q = IX_MBUF_PRIV(sbufp);+	if (q == NULL) {+		printk("ixp: NULL priv in ixp_perform_cb\n");+		return;+	}++	if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {+		printk("ixp: perform failed status=%d\n", status);+		q->ixp_q_crp->crp_etype = EINVAL;+	}++	crypto_done(q->ixp_q_crp);+	kmem_cache_free(qcache, q);+}+++/*+ * registration is not callable at IRQ time,  so we defer+ * to a task queue,  this routines completes the registration for us+ * when the task queue runs+ *+ * Unfortunately this means we cannot tell OCF that the driver is blocked,+ * we do that on the next request.+ */++static void+ixp_registration(void *arg)+{+	struct ixp_data *ixp = arg;+	struct ixp_q *q = NULL;+	IX_MBUF *pri = NULL, *sec = NULL;+	int status = IX_CRYPTO_ACC_STATUS_SUCCESS;++	if (!ixp) {+		printk("ixp: ixp_registration with no arg\n");+		return;+	}++	if (ixp->ixp_ctx_id != -1) {+		ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);+		ixp->ixp_ctx_id = -1;+	}++	if (list_empty(&ixp->ixp_q)) {+		printk("ixp: ixp_registration with no Q\n");+		return;+	}++	/*+	 * setup the primary and secondary buffers+	 */+	q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);+	if (q->ixp_q_acrd) {+		pri = &ixp->ixp_pri_mbuf;+		sec = &ixp->ixp_sec_mbuf;+		IX_MBUF_MLEN(pri)  = IX_MBUF_PKT_LEN(pri) = 128;+		IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);+		IX_MBUF_MLEN(sec)  = IX_MBUF_PKT_LEN(sec) = 128;+		IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);+	}++	/* Only need to register if a crypt op or HMAC op */+	if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||+				ixp->ixp_auth_alg == CRYPTO_MD5)) {+		status = ixCryptoAccCtxRegister(+					&ixp->ixp_ctx,+					pri, sec,+					ixp_register_cb,+					ixp_perform_cb,+					&ixp->ixp_ctx_id);+	}+	else {+		/* Otherwise we start processing pending q */+		schedule_work(&ixp->ixp_pending_work);+	}++	if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)+		return;++	if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {+		printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");+		ixp_blocked = 1;+		/* perhaps we should return EGAIN on queued ops ? */+		return;+	}++	printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);+	ixp->ixp_ctx_id = -1;++	/*+	 * everything waiting is toasted+	 */+	while (!list_empty(&ixp->ixp_q)) {+		q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);+		list_del(&q->ixp_q_list);+		q->ixp_q_crp->crp_etype = ENOENT;+		crypto_done(q->ixp_q_crp);+		kmem_cache_free(qcache, q);+	}+}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void+ixp_registration_wq(struct work_struct *work)+{+	struct ixp_data *ixp = container_of(work, struct ixp_data,+								ixp_registration_work);+	ixp_registration(ixp);+}+#endif++/*+ * Process a request.+ */+static int+ixp_process(device_t dev, struct cryptop *crp, int hint)+{+	struct ixp_data *ixp;+	unsigned int lid;+	struct ixp_q *q = NULL;+	int status;++	dprintk("%s()\n", __FUNCTION__);++	/* Sanity check */+	if (crp == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	crp->crp_etype = 0;++	if (ixp_blocked)+		return ERESTART;++	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	}++	/*+	 * find the session we are using+	 */++	lid = crp->crp_sid & 0xffffffff;+	if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||+			ixp_sessions[lid] == NULL) {+		crp->crp_etype = ENOENT;+		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);+		goto done;+	}+	ixp = ixp_sessions[lid];++	/*+	 * setup a new request ready for queuing+	 */+	q = kmem_cache_alloc(qcache, SLAB_ATOMIC);+	if (q == NULL) {+		dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);+		crp->crp_etype = ENOMEM;+		goto done;+	}+	/*+	 * save some cycles by only zeroing the important bits+	 */+	memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));+	q->ixp_q_ccrd = NULL;+	q->ixp_q_acrd = NULL;+	q->ixp_q_crp = crp;+	q->ixp_q_data = ixp;++	/*+	 * point the cipher and auth descriptors appropriately+	 * check that we have something to do+	 */+	if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)+		q->ixp_q_ccrd = crp->crp_desc;+	else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)+		q->ixp_q_acrd = crp->crp_desc;+	else {+		crp->crp_etype = ENOENT;+		dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);+		goto done;+	}+	if (crp->crp_desc->crd_next) {+		if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)+			q->ixp_q_ccrd = crp->crp_desc->crd_next;+		else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)+			q->ixp_q_acrd = crp->crp_desc->crd_next;+		else {+			crp->crp_etype = ENOENT;+			dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);+			goto done;+		}+	}++	/*+	 * If there is a direction change for this context then we mark it as+	 * unregistered and re-register is for the new direction.  This is not+	 * a very expensive operation and currently only tends to happen when+	 * user-space application are doing benchmarks+	 *+	 * DM - we should be checking for pending requests before unregistering.+	 */+	if (q->ixp_q_ccrd && ixp->ixp_registered &&+			ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {+		dprintk("%s - detected direction change on session\n", __FUNCTION__);+		ixp->ixp_registered = 0;+	}++	/*+	 * if we are registered,  call straight into the perform code+	 */+	if (ixp->ixp_registered) {+		ixp_q_process(q);+		return 0;+	}++	/*+	 * the only part of the context not set in newsession is the direction+	 * dependent parts+	 */+	if (q->ixp_q_ccrd) {+		ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);+		if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {+			ixp->ixp_ctx.operation = q->ixp_q_acrd ?+					IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;+		} else {+			ixp->ixp_ctx.operation = q->ixp_q_acrd ?+					IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;+		}+	} else {+		/* q->ixp_q_acrd must be set if we are here */+		ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;+	}++	status = list_empty(&ixp->ixp_q);+	list_add_tail(&q->ixp_q_list, &ixp->ixp_q);+	if (status)+		schedule_work(&ixp->ixp_registration_work);+	return 0;++done:+	if (q)+		kmem_cache_free(qcache, q);+	crypto_done(crp);+	return 0;+}+++#ifdef __ixp46X+/*+ * key processing support for the ixp465+ */+++/*+ * copy a BN (LE) into a buffer (BE) an fill out the op appropriately+ * assume zeroed and only copy bits that are significant+ */++static int+ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)+{+	unsigned char *src = (unsigned char *) p->crp_p;+	unsigned char *dst;+	int len, bits = p->crp_nbits;++	dprintk("%s()\n", __FUNCTION__);++	if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {+		dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,+				bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);+		return -1;+	}++	len = (bits + 31) / 32; /* the number UINT32's needed */++	dst = (unsigned char *) &buf[len];+	dst--;++	while (bits > 0) {+		*dst-- = *src++;+		bits -= 8;+	}++#if 0 /* no need to zero remaining bits as it is done during request alloc */+	while (dst > (unsigned char *) buf)+		*dst-- = '\0';+#endif++	op->pData = buf;+	op->dataLen = len;+	return 0;+}++/*+ * copy out the result,  be as forgiving as we can about small output buffers+ */++static int+ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)+{+	unsigned char *dst = (unsigned char *) p->crp_p;+	unsigned char *src = (unsigned char *) buf;+	int len, z, bits = p->crp_nbits;++	dprintk("%s()\n", __FUNCTION__);++	len = op->dataLen * sizeof(UINT32);++	/* skip leading zeroes to be small buffer friendly */+	z = 0;+	while (z < len && src[z] == '\0')+		z++;++	src += len;+	src--;+	len -= z;++	while (len > 0 && bits > 0) {+		*dst++ = *src--;+		len--;+		bits -= 8;+	}++	while (bits > 0) {+		*dst++ = '\0';+		bits -= 8;+	}++	if (len > 0) {+		dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",+				__FUNCTION__, len, z, p->crp_nbits / 8);+		return -1;+	}++	return 0;+}+++/*+ * the parameter offsets for exp_mod+ */++#define IXP_PARAM_BASE 0+#define IXP_PARAM_EXP  1+#define IXP_PARAM_MOD  2+#define IXP_PARAM_RES  3++/*+ * key processing complete callback,  is also used to start processing+ * by passing a NULL for pResult+ */++static void+ixp_kperform_cb(+	IxCryptoAccPkeEauOperation operation,+	IxCryptoAccPkeEauOpResult *pResult,+	BOOL carryOrBorrow,+	IxCryptoAccStatus status)+{+	struct ixp_pkq *q, *tmp;+	unsigned long flags;++	dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,+			carryOrBorrow, status);++	/* handle a completed request */+	if (pResult) {+		if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {+			q = ixp_pk_cur;+			if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {+				dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);+				q->pkq_krp->krp_status = ERANGE; /* could do better */+			} else {+				/* copy out the result */+				if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],+						&q->pkq_result, q->pkq_obuf))+					q->pkq_krp->krp_status = ERANGE;+			}+			crypto_kdone(q->pkq_krp);+			kfree(q);+			ixp_pk_cur = NULL;+		} else+			printk("%s - callback with invalid result pointer\n", __FUNCTION__);+	}++	spin_lock_irqsave(&ixp_pkq_lock, flags);+	if (ixp_pk_cur || list_empty(&ixp_pkq)) {+		spin_unlock_irqrestore(&ixp_pkq_lock, flags);+		return;+	}++	list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {++		list_del(&q->pkq_list);+		ixp_pk_cur = q;++		spin_unlock_irqrestore(&ixp_pkq_lock, flags);++		status = ixCryptoAccPkeEauPerform(+				IX_CRYPTO_ACC_OP_EAU_MOD_EXP,+				&q->pkq_op,+				ixp_kperform_cb,+				&q->pkq_result);+	+		if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {+			dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);+			return; /* callback will return here for callback */+		} else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {+			printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);+		} else {+			printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",+					__FUNCTION__, status);+		}+		q->pkq_krp->krp_status = ERANGE; /* could do better */+		crypto_kdone(q->pkq_krp);+		kfree(q);+		spin_lock_irqsave(&ixp_pkq_lock, flags);+	}+	spin_unlock_irqrestore(&ixp_pkq_lock, flags);+}+++static int+ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)+{+	struct ixp_pkq *q;+	int rc = 0;+	unsigned long flags;++	dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,+			krp->krp_param[IXP_PARAM_BASE].crp_nbits,+			krp->krp_param[IXP_PARAM_EXP].crp_nbits,+			krp->krp_param[IXP_PARAM_MOD].crp_nbits,+			krp->krp_param[IXP_PARAM_RES].crp_nbits);+++	if (krp->krp_op != CRK_MOD_EXP) {+		krp->krp_status = EOPNOTSUPP;+		goto err;+	}++	q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);+	if (q == NULL) {+		krp->krp_status = ENOMEM;+		goto err;+	}++	/*+	 * The PKE engine does not appear to zero the output buffer+	 * appropriately, so we need to do it all here.+	 */+	memset(q, 0, sizeof(*q));++	q->pkq_krp = krp;+	INIT_LIST_HEAD(&q->pkq_list);++	if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,+			q->pkq_ibuf0))+		rc = 1;+	if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],+				&q->pkq_op.modExpOpr.e, q->pkq_ibuf1))+		rc = 2;+	if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],+				&q->pkq_op.modExpOpr.N, q->pkq_ibuf2))+		rc = 3;++	if (rc) {+		kfree(q);+		krp->krp_status = ERANGE;+		goto err;+	}++	q->pkq_result.pData           = q->pkq_obuf;+	q->pkq_result.dataLen         =+			(krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;++	spin_lock_irqsave(&ixp_pkq_lock, flags);+	list_add_tail(&q->pkq_list, &ixp_pkq);+	spin_unlock_irqrestore(&ixp_pkq_lock, flags);++	if (!ixp_pk_cur)+		ixp_kperform_cb(0, NULL, 0, 0);+	return (0);++err:+	crypto_kdone(krp);+	return (0);+}++++#ifdef CONFIG_OCF_RANDOMHARVEST+/*+ * We run the random number generator output through SHA so that it+ * is FIPS compliant.+ */++static volatile int sha_done = 0;+static unsigned char sha_digest[20];++static void+ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)+{+	dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);+	if (sha_digest != digest)+		printk("digest error\n");+	if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)+		sha_done = 1;+	else+		sha_done = -status;+}++static int+ixp_read_random(void *arg, u_int32_t *buf, int maxwords)+{+	IxCryptoAccStatus status;+	int i, n, rc;++	dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);+	memset(buf, 0, maxwords * sizeof(*buf));+	status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);+	if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {+		dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",+				__FUNCTION__, status);+		return 0;+	}++	/*+	 * run the random data through SHA to make it look more random+	 */++	n = sizeof(sha_digest); /* process digest bytes at a time */++	rc = 0;+	for (i = 0; i < maxwords; i += n / sizeof(*buf)) {+		if ((maxwords - i) * sizeof(*buf) < n)+			n = (maxwords - i) * sizeof(*buf);+		sha_done = 0;+		status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,+				(UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);+		if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {+			dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);+			return -EIO;+		}+		while (!sha_done)+			schedule();+		if (sha_done < 0) {+			dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);+			return 0;+		}+		memcpy(&buf[i], sha_digest, n);+		rc += n / sizeof(*buf);;+	}++	return rc;+}+#endif /* CONFIG_OCF_RANDOMHARVEST */++#endif /* __ixp46X */++++/*+ * our driver startup and shutdown routines+ */++static int+ixp_init(void)+{+	dprintk("%s(%p)\n", __FUNCTION__, ixp_init);++	if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)+		printk("ixCryptoAccInit failed, assuming already initialised!\n");++	qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,+				SLAB_HWCACHE_ALIGN, NULL+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)+				, NULL+#endif+				  );+	if (!qcache) {+		printk("failed to create Qcache\n");+		return -ENOENT;+	}++	memset(&ixpdev, 0, sizeof(ixpdev));+	softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);++	ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),+				CRYPTOCAP_F_HARDWARE);+	if (ixp_id < 0)+		panic("IXP/OCF crypto device cannot initialize!");++#define	REGISTER(alg) \+	crypto_register(ixp_id,alg,0,0)++	REGISTER(CRYPTO_DES_CBC);+	REGISTER(CRYPTO_3DES_CBC);+	REGISTER(CRYPTO_RIJNDAEL128_CBC);+#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5+	REGISTER(CRYPTO_MD5);+	REGISTER(CRYPTO_SHA1);+#endif+	REGISTER(CRYPTO_MD5_HMAC);+	REGISTER(CRYPTO_SHA1_HMAC);+#undef REGISTER++#ifdef __ixp46X+	spin_lock_init(&ixp_pkq_lock);+	/*+	 * we do not enable the go fast options here as they can potentially+	 * allow timing based attacks+	 *+	 * http://www.openssl.org/news/secadv_20030219.txt+	 */+	ixCryptoAccPkeEauExpConfig(0, 0);+	crypto_kregister(ixp_id, CRK_MOD_EXP, 0);+#ifdef CONFIG_OCF_RANDOMHARVEST+	crypto_rregister(ixp_id, ixp_read_random, NULL);+#endif+#endif++	return 0;+}++static void+ixp_exit(void)+{+	dprintk("%s()\n", __FUNCTION__);+	crypto_unregister_all(ixp_id);+	ixp_id = -1;+	kmem_cache_destroy(qcache);+	qcache = NULL;+}++module_init(ixp_init);+module_exit(ixp_exit);++MODULE_LICENSE("Dual BSD/GPL");+MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");+MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");diff -Nur linux-2.6.36.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.36/crypto/ocf/ixp4xx/Makefile--- linux-2.6.36.orig/crypto/ocf/ixp4xx/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ixp4xx/Makefile	2010-11-09 20:28:05.113478850 +0100@@ -0,0 +1,104 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++#+# You will need to point this at your Intel ixp425 includes,  this portion+# of the Makefile only really works under SGLinux with the appropriate libs+# installed.  They can be downloaded from http://www.snapgear.org/+#+ifeq ($(CONFIG_CPU_IXP46X),y)+IXPLATFORM = ixp46X+else+ifeq ($(CONFIG_CPU_IXP43X),y)+IXPLATFORM = ixp43X+else+IXPLATFORM = ixp42X+endif+endif++ifdef CONFIG_IXP400_LIB_2_4+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw+OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal+endif+ifdef CONFIG_IXP400_LIB_2_1+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw+OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal+endif+ifdef CONFIG_IXP400_LIB_2_0+IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw+OSAL_DIR     = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal+endif+ifdef IX_XSCALE_SW+ifdef CONFIG_IXP400_LIB_2_4+IXP_CFLAGS = \+	-I$(ROOTDIR)/. \+	-I$(IX_XSCALE_SW)/src/include \+	-I$(OSAL_DIR)/common/include/ \+	-I$(OSAL_DIR)/common/include/modules/ \+	-I$(OSAL_DIR)/common/include/modules/ddk/ \+	-I$(OSAL_DIR)/common/include/modules/bufferMgt/ \+	-I$(OSAL_DIR)/common/include/modules/ioMem/ \+	-I$(OSAL_DIR)/common/os/linux/include/ \+	-I$(OSAL_DIR)/common/os/linux/include/core/  \+	-I$(OSAL_DIR)/common/os/linux/include/modules/ \+	-I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \+	-I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \+	-I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \+	-I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \+	-I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \+	-DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \+	-DUSE_IXP4XX_CRYPTO+else+IXP_CFLAGS = \+	-I$(ROOTDIR)/. \+	-I$(IX_XSCALE_SW)/src/include \+	-I$(OSAL_DIR)/ \+	-I$(OSAL_DIR)/os/linux/include/ \+	-I$(OSAL_DIR)/os/linux/include/modules/ \+	-I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \+	-I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \+	-I$(OSAL_DIR)/os/linux/include/core/  \+	-I$(OSAL_DIR)/os/linux/include/platforms/ \+	-I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \+	-I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \+	-I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \+	-I$(OSAL_DIR)/os/linux/include/core/ \+	-I$(OSAL_DIR)/include/ \+	-I$(OSAL_DIR)/include/modules/ \+	-I$(OSAL_DIR)/include/modules/bufferMgt/ \+	-I$(OSAL_DIR)/include/modules/ioMem/ \+	-I$(OSAL_DIR)/include/platforms/ \+	-I$(OSAL_DIR)/include/platforms/ixp400/ \+	-DUSE_IXP4XX_CRYPTO+endif+endif+ifdef CONFIG_IXP400_LIB_1_4+IXP_CFLAGS   = \+	-I$(ROOTDIR)/. \+	-I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \+	-I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \+	-DUSE_IXP4XX_CRYPTO+endif+ifndef IXPDIR+IXPDIR = ixp-version-is-not-supported+endif++ifeq ($(CONFIG_CPU_IXP46X),y)+IXP_CFLAGS += -D__ixp46X+else+ifeq ($(CONFIG_CPU_IXP43X),y)+IXP_CFLAGS += -D__ixp43X+else+IXP_CFLAGS += -D__ixp42X+endif+endif++obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o++obj ?= .+EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/Kconfig linux-2.6.36/crypto/ocf/Kconfig--- linux-2.6.36.orig/crypto/ocf/Kconfig	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/Kconfig	2010-11-09 20:28:05.141255099 +0100@@ -0,0 +1,119 @@+menu "OCF Configuration"++config OCF_OCF+	tristate "OCF (Open Cryptograhic Framework)"+	help+	  A linux port of the OpenBSD/FreeBSD crypto framework.++config OCF_RANDOMHARVEST+	bool "crypto random --- harvest entropy for /dev/random"+	depends on OCF_OCF+	help+	  Includes code to harvest random numbers from devices that support it.++config OCF_FIPS+	bool "enable fips RNG checks"+	depends on OCF_OCF && OCF_RANDOMHARVEST+	help+	  Run all RNG provided data through a fips check before+	  adding it /dev/random's entropy pool.++config OCF_CRYPTODEV+	tristate "cryptodev (user space support)"+	depends on OCF_OCF+	help+	  The user space API to access crypto hardware.++config OCF_CRYPTOSOFT+	tristate "cryptosoft (software crypto engine)"+	depends on OCF_OCF+	help+	  A software driver for the OCF framework that uses+	  the kernel CryptoAPI.++config OCF_SAFE+	tristate "safenet (HW crypto engine)"+	depends on OCF_OCF+	help+	  A driver for a number of the safenet Excel crypto accelerators.+	  Currently tested and working on the 1141 and 1741.++config OCF_IXP4XX+	tristate "IXP4xx (HW crypto engine)"+	depends on OCF_OCF+	help+	  XScale IXP4xx crypto accelerator driver.  Requires the+	  Intel Access library.++config OCF_IXP4XX_SHA1_MD5+	bool "IXP4xx SHA1 and MD5 Hashing"+	depends on OCF_IXP4XX+	help+	  Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.+	  Note: this is MUCH slower than using cryptosoft (software crypto engine).++config OCF_HIFN+	tristate "hifn (HW crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for various HIFN based crypto accelerators.+	  (7951, 7955, 7956, 7751, 7811)++config OCF_HIFNHIPP+	tristate "Hifn HIPP (HW packet crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for various HIFN (HIPP) based crypto accelerators+	  (7855)++config OCF_TALITOS+	tristate "talitos (HW crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for Freescale's security engine (SEC/talitos).++config OCF_PASEMI+	tristate "pasemi (HW crypto engine)"+	depends on OCF_OCF && PPC_PASEMI+	help+	  OCF driver for the PA Semi PWRficient DMA Engine++config OCF_EP80579+	tristate "ep80579 (HW crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for the Intel EP80579 Integrated Processor Product Line.++config OCF_CRYPTOCTEON+	tristate "cryptocteon (HW crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for the Cavium OCTEON Processors.++config OCF_KIRKWOOD+	tristate "kirkwood (HW crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for the Marvell Kirkwood (88F6xxx) Processors.++config OCF_C7108+	tristate "Micronas 7108 (HW crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for the Microna 7108 Cipher processors.++config OCF_OCFNULL+	tristate "ocfnull (fake crypto engine)"+	depends on OCF_OCF+	help+	  OCF driver for measuring ipsec overheads (does no crypto)++config OCF_BENCH+	tristate "ocf-bench (HW crypto in-kernel benchmark)"+	depends on OCF_OCF+	help+	  A very simple encryption test for the in-kernel interface+	  of OCF.  Also includes code to benchmark the IXP Access library+	  for comparison.++endmenudiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c	2010-11-09 20:28:05.189557501 +0100@@ -0,0 +1,317 @@+/* rijndael-alg-ref.c   v2.0   August '99+ * Reference ANSI C code+ * authors: Paulo Barreto+ *          Vincent Rijmen, K.U.Leuven+ *+ * This code is placed in the public domain.+ */++#include "mvOs.h"++#include "mvAesAlg.h"++#include "mvAesBoxes.dat"+++MV_U8 mul1(MV_U8 aa, MV_U8 bb);+void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);+void ShiftRow128Enc(MV_U8 a[4][MAXBC]);+void ShiftRow128Dec(MV_U8 a[4][MAXBC]);+void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);+void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);+void InvMixColumn(MV_U8 a[4][MAXBC]);+++#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])+                         +MV_U8 mul1(MV_U8 aa, MV_U8 bb)+{+    return mask[bb] & Alogtable[aa + Logtable[bb]];+}+++void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC) +{+	/* Exor corresponding text input and round key input bytes+	 */+    ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];+    ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];+    ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];+    ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];++}++void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {+	/* Row 0 remains unchanged+	 * The other three rows are shifted a variable amount+	 */+	MV_U8 tmp[MAXBC];+	+    tmp[0] = a[1][1];+    tmp[1] = a[1][2];+    tmp[2] = a[1][3];+    tmp[3] = a[1][0];++    ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];+     /*+    a[1][0] = tmp[0];+    a[1][1] = tmp[1];+    a[1][2] = tmp[2];+    a[1][3] = tmp[3];+       */+    tmp[0] = a[2][2];+    tmp[1] = a[2][3];+    tmp[2] = a[2][0];+    tmp[3] = a[2][1];++    ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];+      /*+    a[2][0] = tmp[0];+    a[2][1] = tmp[1];+    a[2][2] = tmp[2];+    a[2][3] = tmp[3];+    */+    tmp[0] = a[3][3];+    tmp[1] = a[3][0];+    tmp[2] = a[3][1];+    tmp[3] = a[3][2];++    ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];+    /*+    a[3][0] = tmp[0];+    a[3][1] = tmp[1];+    a[3][2] = tmp[2];+    a[3][3] = tmp[3];+    */+}  ++void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {+	/* Row 0 remains unchanged+	 * The other three rows are shifted a variable amount+	 */+   	MV_U8 tmp[MAXBC];+	+    tmp[0] = a[1][3];+    tmp[1] = a[1][0];+    tmp[2] = a[1][1];+    tmp[3] = a[1][2];++    ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];+    /*+    a[1][0] = tmp[0];+    a[1][1] = tmp[1];+    a[1][2] = tmp[2];+    a[1][3] = tmp[3];+    */++    tmp[0] = a[2][2];+    tmp[1] = a[2][3];+    tmp[2] = a[2][0];+    tmp[3] = a[2][1];++    ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];+    /*+    a[2][0] = tmp[0];+    a[2][1] = tmp[1];+    a[2][2] = tmp[2];+    a[2][3] = tmp[3];+    */++    tmp[0] = a[3][1];+    tmp[1] = a[3][2];+    tmp[2] = a[3][3];+    tmp[3] = a[3][0];++    ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];+    /*+    a[3][0] = tmp[0];+    a[3][1] = tmp[1];+    a[3][2] = tmp[2];+    a[3][3] = tmp[3];+    */+}  ++void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {+	/* Replace every byte of the input by the byte at that place+	 * in the nonlinear S-box+	 */+	int i, j;+	+	for(i = 0; i < 4; i++)+		for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;+}+   +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {+        /* Mix the four bytes of every column in a linear way+	 */+	MV_U8 b[4][MAXBC];+	int i, j;+		+	for(j = 0; j < 4; j++){+        b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];+        b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];+        b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];+        b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];+    }+	for(i = 0; i < 4; i++)+		/*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/+        ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;+}++void InvMixColumn(MV_U8 a[4][MAXBC]) {+        /* Mix the four bytes of every column in a linear way+	 * This is the opposite operation of Mixcolumn+	 */+	MV_U8 b[4][MAXBC];+	int i, j;+	+	for(j = 0; j < 4; j++){+        b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);+        b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);+        b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);+        b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);+    }+	for(i = 0; i < 4; i++)+		/*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/+        ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];+}++int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC]) +{+	/* Calculate the necessary round keys+	 * The number of calculations depends on keyBits and blockBits+	 */+	int KC, BC, ROUNDS;+	int i, j, t, rconpointer = 0;+	MV_U8 tk[4][MAXKC];   ++	switch (keyBits) {+	case 128: KC = 4; break;+	case 192: KC = 6; break;+	case 256: KC = 8; break;+	default : return (-1);+	}++	switch (blockBits) {+	case 128: BC = 4; break;+	case 192: BC = 6; break;+	case 256: BC = 8; break;+	default : return (-2);+	}++	switch (keyBits >= blockBits ? keyBits : blockBits) {+	case 128: ROUNDS = 10; break;+	case 192: ROUNDS = 12; break;+	case 256: ROUNDS = 14; break;+	default : return (-3); /* this cannot happen */+	}++	+	for(j = 0; j < KC; j++)+		for(i = 0; i < 4; i++)+			tk[i][j] = k[i][j];+	t = 0;+	/* copy values into round key array */+	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)+		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];+		+	while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */+		/* calculate new values */+		for(i = 0; i < 4; i++)+			tk[i][0] ^= S[tk[(i+1)%4][KC-1]];+		tk[0][0] ^= rcon[rconpointer++];++		if (KC != 8)+			for(j = 1; j < KC; j++)+				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];+		else {+			for(j = 1; j < KC/2; j++)+				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];+			for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];+			for(j = KC/2 + 1; j < KC; j++)+				for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];+	}+	/* copy values into round key array */+	for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)+		for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];+	}		++	return 0;+}+      +        ++int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)+{+	/* Encryption of one block. +	 */+	int r, BC, ROUNDS;++    BC = 4;+    ROUNDS = rounds;++	/* begin with a key addition+	 */++	KeyAddition(a,rk[0],BC); ++    /* ROUNDS-1 ordinary rounds+	 */+	for(r = 1; r < ROUNDS; r++) {+		Substitution(a,S);+		ShiftRow128Enc(a);+		MixColumn(a, rk[r]);+		/*KeyAddition(a,rk[r],BC);*/+	}+	+	/* Last round is special: there is no MixColumn+	 */+	Substitution(a,S);+	ShiftRow128Enc(a);+	KeyAddition(a,rk[ROUNDS],BC);++	return 0;+}   +++int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)+{+	int r, BC, ROUNDS;+	+    BC = 4;+    ROUNDS = rounds;++	/* To decrypt: apply the inverse operations of the encrypt routine,+	 *             in opposite order+	 * +	 * (KeyAddition is an involution: it 's equal to its inverse)+	 * (the inverse of Substitution with table S is Substitution with the inverse table of S)+	 * (the inverse of Shiftrow is Shiftrow over a suitable distance)+	 */++        /* First the special round:+	 *   without InvMixColumn+	 *   with extra KeyAddition+	 */+	KeyAddition(a,rk[ROUNDS],BC);+    ShiftRow128Dec(a);               +	Substitution(a,Si);+	+	/* ROUNDS-1 ordinary rounds+	 */+	for(r = ROUNDS-1; r > 0; r--) {+		KeyAddition(a,rk[r],BC);+		InvMixColumn(a);      +		ShiftRow128Dec(a);               +		Substitution(a,Si);++	}+	+	/* End with the extra key addition+	 */+	+	KeyAddition(a,rk[0],BC);    ++	return 0;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h	2010-11-09 20:28:05.222495460 +0100@@ -0,0 +1,19 @@+/* rijndael-alg-ref.h   v2.0   August '99+ * Reference ANSI C code+ * authors: Paulo Barreto+ *          Vincent Rijmen, K.U.Leuven+ */+#ifndef __RIJNDAEL_ALG_H+#define __RIJNDAEL_ALG_H++#define MAXBC				(128/32)+#define MAXKC				(256/32)+#define MAXROUNDS			14+++int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);++int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);+int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);++#endif /* __RIJNDAEL_ALG_H */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c	2010-11-09 20:28:05.264499847 +0100@@ -0,0 +1,312 @@+/* rijndael-api-ref.c   v2.1   April 2000+ * Reference ANSI C code+ * authors: v2.0 Paulo Barreto+ *               Vincent Rijmen, K.U.Leuven+ *          v2.1 Vincent Rijmen, K.U.Leuven+ *+ * This code is placed in the public domain.+ */+#include "mvOs.h"++#include "mvAes.h"+#include "mvAesAlg.h"+++/*  Defines:+	Add any additional defines you need+*/++#define     MODE_ECB        1    /*  Are we ciphering in ECB mode?   */+#define     MODE_CBC        2    /*  Are we ciphering in CBC mode?   */+#define     MODE_CFB1       3    /*  Are we ciphering in 1-bit CFB mode? */+++int     aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)+{+    MV_U8   W[MAXROUNDS+1][4][MAXBC];+	MV_U8   k[4][MAXKC];+    MV_U8   j;+	int     i, rounds, KC;+	+	if (expandedKey == NULL) +    {+		return AES_BAD_KEY_INSTANCE;+	}++	if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256))) +    { +		return AES_BAD_KEY_MAT;+	}++	if (keyMaterial == NULL) +    {+		return AES_BAD_KEY_MAT;+	}++	/* initialize key schedule: */ + 	for(i=0; i<keyLen/8; i++) +    {+		j = keyMaterial[i];+		k[i % 4][i / 4] = j; +	}	+	+	rijndaelKeySched (k, keyLen, blockLen, W);+#ifdef MV_AES_DEBUG+    {+        MV_U8*  pW = &W[0][0][0];+        int     x;++        mvOsPrintf("Expended Key: size = %d\n", sizeof(W));+        for(i=0; i<sizeof(W); i++)+        {+            mvOsPrintf("%02x ", pW[i]);+        }+        for(i=0; i<MAXROUNDS+1; i++)+        {+            mvOsPrintf("\n Round #%02d: ", i);+            for(x=0; x<MAXBC; x++)+            {+                mvOsPrintf("%02x%02x%02x%02x ", +                    W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);+            }+            mvOsPrintf("\n");+        }+    }+#endif /* MV_AES_DEBUG */+  	switch (keyLen) +    {+	    case 128: +            rounds = 10;+            KC = 4; +            break;+	    case 192: +            rounds = 12;+            KC = 6; +            break;+	    case 256: +            rounds = 14;+            KC = 8; +            break;+	    default : +            return (-1);+	}++    for(i=0; i<MAXBC; i++)+    {+        for(j=0; j<4; j++)+        {+            expandedKey[i*4+j] = W[rounds][j][i];+        }+    }+    for(; i<KC; i++)+    {+        for(j=0; j<4; j++)+        {+            expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];+        }+    }++	+	return 0;+}++int     aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int  keyLen, +                        MV_U32 *plain, int numBlocks, MV_U32 *cipher)+{+	int     i, j, t;+	MV_U8   block[4][MAXBC];+    int     rounds;+    char    *input, *outBuffer;++    input = (char*)plain;+    outBuffer = (char*)cipher;++        /* check parameter consistency: */+    if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256))) +    {+        return AES_BAD_KEY_MAT;+    }+    if ((mode != MODE_ECB && mode != MODE_CBC))+    {+        return AES_BAD_CIPHER_STATE;+    }++	switch (keyLen) +    {+	    case 128: rounds = 10; break;+	    case 192: rounds = 12; break;+	    case 256: rounds = 14; break;+	    default : return (-3); /* this cannot happen */+	}++	+	switch (mode) +    {+	    case MODE_ECB: +		    for (i = 0; i < numBlocks; i++) +            {+			    for (j = 0; j < 4; j++) +                {+				    for(t = 0; t < 4; t++)+				        /* parse input stream into rectangular array */+					    block[t][j] = input[16*i+4*j+t] & 0xFF;+			    }                           +			    rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);+			    for (j = 0; j < 4; j++) +                {           +				    /* parse rectangular array into output ciphertext bytes */+				    for(t = 0; t < 4; t++)+                        outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];++			    }+		    }+		    break;+		+	    case MODE_CBC:+		    for (j = 0; j < 4; j++) +            {+			    for(t = 0; t < 4; t++)+			    /* parse initial value into rectangular array */+					block[t][j] = IV[t+4*j] & 0xFF;+			}+		    for (i = 0; i < numBlocks; i++) +            {+			    for (j = 0; j < 4; j++) +                {+				    for(t = 0; t < 4; t++)+				        /* parse input stream into rectangular array and exor with +				        IV or the previous ciphertext */+					    block[t][j] ^= input[16*i+4*j+t] & 0xFF;+			    }+			    rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);+			    for (j = 0; j < 4; j++) +                {+				    /* parse rectangular array into output ciphertext bytes */+				    for(t = 0; t < 4; t++)+					    outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];+			    }+		    }+		    break;+	+	    default: return AES_BAD_CIPHER_STATE;+	}+	+	return 0;+}++int     aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int  keyLen, +                            MV_U32 *srcData, int numBlocks, MV_U32 *dstData)+{+	int     i, j, t;+	MV_U8   block[4][MAXBC];+    MV_U8   iv[4][MAXBC];    +    int     rounds;+    char    *input, *outBuffer;++    input = (char*)srcData;+    outBuffer = (char*)dstData;++    if (expandedKey == NULL) +    {+		return AES_BAD_KEY_MAT;+	}++    /* check parameter consistency: */+    if (keyLen != 128 && keyLen != 192 && keyLen != 256)+    {+        return AES_BAD_KEY_MAT;+    }+    if ((mode != MODE_ECB && mode != MODE_CBC)) +    {+        return AES_BAD_CIPHER_STATE;+    }++	switch (keyLen) +    {+	    case 128: rounds = 10; break;+	    case 192: rounds = 12; break;+	    case 256: rounds = 14; break;+	    default : return (-3); /* this cannot happen */+	}++	+	switch (mode) +    {+	    case MODE_ECB: +		    for (i = 0; i < numBlocks; i++) +            {+			    for (j = 0; j < 4; j++) +                {+				    for(t = 0; t < 4; t++)+                    {+				        /* parse input stream into rectangular array */+					    block[t][j] = input[16*i+4*j+t] & 0xFF;+                    }+			    }+			    rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);+			    for (j = 0; j < 4; j++) +                {+				    /* parse rectangular array into output ciphertext bytes */+				    for(t = 0; t < 4; t++)+					    outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];+			    }+		    }+		    break;+		+	    case MODE_CBC:+		    /* first block */+		    for (j = 0; j < 4; j++) +            {+			    for(t = 0; t < 4; t++)+                {+			        /* parse input stream into rectangular array */+				    block[t][j] = input[4*j+t] & 0xFF;+                    iv[t][j] = block[t][j];+                }+		    }+		    rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);+		+		    for (j = 0; j < 4; j++) +            {+			    /* exor the IV and parse rectangular array into output ciphertext bytes */+			    for(t = 0; t < 4; t++)+                {+				    outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);+                    IV[t+4*j] = iv[t][j];+                }+		    }+		+		    /* next blocks */+		    for (i = 1; i < numBlocks; i++) +            {+			    for (j = 0; j < 4; j++) +                {+				    for(t = 0; t < 4; t++)+                    {+				        /* parse input stream into rectangular array */+                        iv[t][j] = input[16*i+4*j+t] & 0xFF;+					    block[t][j] = iv[t][j];+                    }+			    }+			    rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);+			+			    for (j = 0; j < 4; j++) +                {+				    /* exor previous ciphertext block and parse rectangular array +				       into output ciphertext bytes */+				    for(t = 0; t < 4; t++)+                    {+					    outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);+                        IV[t+4*j] = iv[t][j];+                    }+			    }+		    }+		    break;+	+	    default: return AES_BAD_CIPHER_STATE;+	}+	+	return 0;+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAes.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/AES/mvAes.h	2010-11-09 20:28:05.292495461 +0100@@ -0,0 +1,62 @@+/* mvAes.h   v2.0   August '99+ * Reference ANSI C code+ */++/*  AES Cipher header file for ANSI C Submissions+      Lawrence E. Bassham III+      Computer Security Division+      National Institute of Standards and Technology++      April 15, 1998++    This sample is to assist implementers developing to the Cryptographic +API Profile for AES Candidate Algorithm Submissions.  Please consult this +document as a cross-reference.++    ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE+MUST BE DOCUMENTED.  CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH+THE STRING "CHANGE POSSIBLE".  FUNCTION CALLS AND THEIR PARAMETERS CANNOT +BE CHANGED.  STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE +IMPLEMENTATION SPECIFIC INFORMATION.+*/++/*  Includes:+	Standard include files+*/++#include "mvOs.h"+++/*  Error Codes - CHANGE POSSIBLE: inclusion of additional error codes  */++/*  Key direction is invalid, e.g., unknown value */+#define     AES_BAD_KEY_DIR        -1  ++/*  Key material not of correct length */+#define     AES_BAD_KEY_MAT        -2  ++/*  Key passed is not valid  */+#define     AES_BAD_KEY_INSTANCE   -3  ++/*  Params struct passed to cipherInit invalid */+#define     AES_BAD_CIPHER_MODE    -4  ++/*  Cipher in wrong state (e.g., not initialized) */+#define     AES_BAD_CIPHER_STATE   -5  ++#define     AES_BAD_CIPHER_INSTANCE   -7 +++/*  Function protoypes  */+/*  CHANGED: makeKey(): parameter blockLen added+                        this parameter is absolutely necessary if you want to+			setup the round keys in a variable block length setting +	     cipherInit(): parameter blockLen added (for obvious reasons)		+ */+int     aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);+int     aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int  keyLen, +                    MV_U32 *plain, int numBlocks, MV_U32 *cipher);+int     aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int  keyLen, +                    MV_U32 *plain, int numBlocks, MV_U32 *cipher);++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.c	2010-11-09 20:28:05.302495516 +0100@@ -0,0 +1,3126 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "cesa/mvCesa.h"++#include "ctrlEnv/mvCtrlEnvLib.h"+#undef CESA_DEBUG+++/********** Global variables **********/++/*  If request size is more than MV_CESA_MAX_BUF_SIZE the+ *  request is processed as fragmented request.+ */++MV_CESA_STATS           cesaStats;++MV_BUF_INFO             cesaSramSaBuf;+short                   cesaLastSid = -1;+MV_CESA_SA*             pCesaSAD = NULL;+MV_U16                  cesaMaxSA = 0;++MV_CESA_REQ*            pCesaReqFirst = NULL;+MV_CESA_REQ*            pCesaReqLast = NULL;+MV_CESA_REQ*            pCesaReqEmpty = NULL;+MV_CESA_REQ*            pCesaReqProcess = NULL;+int                     cesaQueueDepth = 0;+int                     cesaReqResources = 0;++MV_CESA_SRAM_MAP*       cesaSramVirtPtr = NULL;+MV_U32                  cesaCryptEngBase = 0;+void			*cesaOsHandle = NULL;+#if (MV_CESA_VERSION >= 3)+MV_U32			cesaChainLength = 0;+int                     chainReqNum = 0;+MV_U32			chainIndex = 0;+MV_CESA_REQ*  		pNextActiveChain = 0;+MV_CESA_REQ*		pEndCurrChain = 0;+MV_BOOL			isFirstReq = MV_TRUE;+#endif++static INLINE MV_U8*  mvCesaSramAddrGet(void)+{+#ifdef MV_CESA_NO_SRAM+    return (MV_U8*)cesaSramVirtPtr;+#else+    return (MV_U8*)cesaCryptEngBase;+#endif /* MV_CESA_NO_SRAM */+}++static INLINE MV_ULONG    mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)+{+#ifdef MV_CESA_NO_SRAM+    return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);+#else+    return (MV_ULONG)pSramVirt;+#endif /* MV_CESA_NO_SRAM */+}++/* Internal Function prototypes */++static INLINE void      mvCesaSramDescrBuild(MV_U32 config, int frag,+                                 int cryptoOffset, int ivOffset, int cryptoLength,+                                 int macOffset, int digestOffset, int macLength, int macTotalLen,+                                 MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);++static INLINE void      mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);++static INLINE int       mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf, +                                MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,+                                int offset, int copySize, MV_BOOL skipFlush);++static void        mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,+                                    unsigned char innerIV[], unsigned char outerIV[]);++static MV_STATUS   mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,+                                          int macDataSize);++static MV_CESA_COMMAND*   mvCesaCtrModeInit(void);++static MV_STATUS   mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);+static MV_STATUS   mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);+static void        mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);++static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);+static MV_STATUS   mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);++static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);+static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);++static INLINE void      mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq, +                               int cryptoOffset, int macOffset,+                               int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);+static MV_STATUS        mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);+++/* Go to the next request in the request queue */+static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)+{+    if(pReq == pCesaReqLast)+        return pCesaReqFirst;++    return pReq+1;+}++#if (MV_CESA_VERSION >= 3)+/* Go to the previous request in the request queue */+static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)+{+    if(pReq == pCesaReqFirst)+        return pCesaReqLast;++    return pReq-1;+}++#endif+++static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)+{+    int frag;++#if (MV_CESA_VERSION >= 3)+    pReq->state = MV_CESA_CHAIN;+#else+    pReq->state = MV_CESA_PROCESS;+#endif+    cesaStats.startCount++;++    if(pReq->fragMode == MV_CESA_FRAG_NONE)+    {+        frag = 0;+    }+    else+    {+        frag = pReq->frags.nextFrag;+        pReq->frags.nextFrag++;+    }+#if (MV_CESA_VERSION >= 2)+    /* Enable TDMA engine */+    MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);+    MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG, +            (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));+#else+    /* Enable IDMA engine */+    MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);+    MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0), +            (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));+#endif /* MV_CESA_VERSION >= 2 */++#if defined(MV_BRIDGE_SYNC_REORDER) +    mvOsBridgeReorderWA();+#endif++    /* Start Accelerator */+    MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);+}+++/*******************************************************************************+* mvCesaHalInit - Initialize the CESA driver+*+* DESCRIPTION:+*       This function initialize the CESA driver.+*       1) Session database+*       2) Request queue+*       4) DMA descriptor lists - one list per request. Each list+*           has MV_CESA_MAX_DMA_DESC descriptors.+*+* INPUT:+*       numOfSession    - maximum number of supported sessions+*       queueDepth      - number of elements in the request queue.+*       pSramBase       - virtual address of Sram+*	osHandle	- A handle used by the OS to allocate memory for the +*			  module (Passed to the OS Services layer)+*+* RETURN:+*       MV_OK           - Success+*       MV_NO_RESOURCE  - Fail, can't allocate resources:+*                         Session database, request queue,+*                         DMA descriptors list, LRU cache database.+*       MV_NOT_ALIGNED  - Sram base address is not 8 byte aligned.+*+*******************************************************************************/+MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,+			 void *osHandle)+{+    int     i, req;+    MV_U32  descOffsetReg, configReg;+    MV_CESA_SRAM_SA *pSramSA;+++    mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",+                numOfSession, queueDepth, pSramBase);++    cesaOsHandle = osHandle;+    /* Create Session database */+    pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);+    if(pCesaSAD == NULL)+    {+        mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",+                    sizeof(MV_CESA_SA)*numOfSession, numOfSession);+        mvCesaFinish();+        return MV_NO_RESOURCE;+    }+    memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);+    cesaMaxSA = numOfSession;++    /* Allocate imag of sramSA in the DRAM */+    cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession + +                                    CPU_D_CACHE_LINE_SIZE;++    cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,+						  &cesaSramSaBuf.bufPhysAddr,+						  &cesaSramSaBuf.memHandle);+        +    if(cesaSramSaBuf.bufVirtPtr == NULL)+    {+        mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n", +                    cesaSramSaBuf.bufSize);+        mvCesaFinish();+        return MV_NO_RESOURCE;+    }+    memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize); +    pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr, +                                                       CPU_D_CACHE_LINE_SIZE);+    for(i=0; i<numOfSession; i++)+    {+        pCesaSAD[i].pSramSA = &pSramSA[i];+    }++    /* Create request queue */+    pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);+    if(pCesaReqFirst == NULL)+    {+        mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",+                    sizeof(MV_CESA_REQ)*queueDepth, queueDepth);+        mvCesaFinish();+        return MV_NO_RESOURCE;+    }+    memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);+    pCesaReqEmpty = pCesaReqFirst;+    pCesaReqLast = pCesaReqFirst + (queueDepth-1);+    pCesaReqProcess = pCesaReqEmpty;+    cesaQueueDepth = queueDepth;+    cesaReqResources = queueDepth;+#if (MV_CESA_VERSION >= 3)+    cesaChainLength = MAX_CESA_CHAIN_LENGTH; +#endif+    /* pSramBase must be 8 byte aligned */+    if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )+    {+        mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",+                pSramBase);+        mvCesaFinish();+        return MV_NOT_ALIGNED;+    }+    cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;+    +    cesaCryptEngBase = cryptEngBase;++    /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/++    /* Clear registers */+    MV_REG_WRITE( MV_CESA_CFG_REG, 0);+    MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);+    MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);++    /* Initialize DMA descriptor lists for all requests in Request queue */+    descOffsetReg = configReg = 0;+    for(req=0; req<queueDepth; req++)+    {+        int             frag;+        MV_CESA_REQ*    pReq;+        MV_DMA_DESC*    pDmaDesc;++        pReq = &pCesaReqFirst[req];++        pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS + +                                        CPU_D_CACHE_LINE_SIZE;++	pReq->cesaDescBuf.bufVirtPtr = +		mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,+				   &pReq->cesaDescBuf.bufPhysAddr,+				   &pReq->cesaDescBuf.memHandle);++        if(pReq->cesaDescBuf.bufVirtPtr == NULL)+        {+            mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n", +                        req, pReq->cesaDescBuf.bufSize);+                mvCesaFinish();+                return MV_NO_RESOURCE;+            }+        memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize); +        pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr, +                                                                CPU_D_CACHE_LINE_SIZE);++        pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS + +                                    CPU_D_CACHE_LINE_SIZE;++        pReq->dmaDescBuf.bufVirtPtr = +		mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,+				   &pReq->dmaDescBuf.bufPhysAddr,+				   &pReq->dmaDescBuf.memHandle);++        if(pReq->dmaDescBuf.bufVirtPtr == NULL)+        {+            mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n", +                        req, pReq->dmaDescBuf.bufSize);+            mvCesaFinish();+            return MV_NO_RESOURCE;+        }+        memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize); +        pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr, +                                                       CPU_D_CACHE_LINE_SIZE);++        for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)+        {+            MV_CESA_DMA*    pDma = &pReq->dma[frag];++            pDma->pDmaFirst = pDmaDesc;+            pDma->pDmaLast = NULL;+            +            for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)+            {+                /* link all DMA descriptors together */+                pDma->pDmaFirst[i].phyNextDescPtr = +                        MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));+            }+            pDma->pDmaFirst[i].phyNextDescPtr = 0;+            mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));        ++            pDmaDesc += MV_CESA_MAX_DMA_DESC;+        }        +    }+    /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/+    descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());+    MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);++    configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);+#if (MV_CESA_VERSION >= 3)+    configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;+#endif++#if (MV_CESA_VERSION >= 2)+    /* Initialize TDMA engine */+    MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);+    MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);+    MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);+#else+    /* Initialize IDMA #0 engine */+    MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);+    MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);+    MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);+    MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE+#ifdef MV_CPU_LE+      		| ICCHR_DESC_BYTE_SWAP_EN+#endif+		 );+    /* Clear Cause Byte of IDMA channel to be used */+    MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));+    MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);+#endif /* (MV_CESA_VERSION >= 2) */++    /* Set CESA configuration registers */+    MV_REG_WRITE( MV_CESA_CFG_REG, configReg);+    mvCesaDebugStatsClear();++    return MV_OK;+}++/*******************************************************************************+* mvCesaFinish - Shutdown the CESA driver+*+* DESCRIPTION:+*       This function shutdown the CESA driver and free all allocted resources.+*+* INPUT:    None+*+* RETURN:+*       MV_OK   - Success+*       Other   - Fail+*+*******************************************************************************/+MV_STATUS   mvCesaFinish (void)+{+    int             req;+    MV_CESA_REQ*    pReq;++    mvOsPrintf("mvCesaFinish: \n");++    cesaSramVirtPtr = NULL;++    /* Free all resources: DMA list, etc. */+    for(req=0; req<cesaQueueDepth; req++)+    {+    	pReq = &pCesaReqFirst[req];+        if(pReq->dmaDescBuf.bufVirtPtr != NULL)+        {+        	mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,+				 pReq->dmaDescBuf.bufPhysAddr,+				 pReq->dmaDescBuf.bufVirtPtr,+				 pReq->dmaDescBuf.memHandle);+        }+        if(pReq->cesaDescBuf.bufVirtPtr != NULL)+        {+                mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,+				 pReq->cesaDescBuf.bufPhysAddr,+				 pReq->cesaDescBuf.bufVirtPtr,+				 pReq->cesaDescBuf.memHandle);+        }+    }+#if (MV_CESA_VERSION < 2)+    MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);+#endif /* (MV_CESA_VERSION < 2) */++    /* Free request queue */+    if(pCesaReqFirst != NULL)+    {+        mvOsFree(pCesaReqFirst);+        pCesaReqFirst = pCesaReqLast = NULL;+        pCesaReqEmpty = pCesaReqProcess = NULL;+        cesaQueueDepth = cesaReqResources = 0;+    }+    /* Free SA database */+    if(pCesaSAD != NULL)+    {+        mvOsFree(pCesaSAD);+        pCesaSAD = NULL;+        cesaMaxSA = 0;+    }+    MV_REG_WRITE( MV_CESA_CFG_REG, 0);+    MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);+    MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);++    return MV_OK;+}++/*******************************************************************************+* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode+*+* DESCRIPTION:+*    This function set IV value using by Crypto algorithms in CBC mode.+*   Each channel has its own IV value.+*   This function gets IV value from the caller. If no IV value passed from+*   the caller or only part of IV passed, the function will init the rest part+*   of IV value (or the whole IV) by random value.+*+* INPUT:+*       MV_U8*  pIV     - Pointer to IV value supplied by user. If pIV==NULL+*                       the function will generate random IV value.+*       int     ivSize  - size (in bytes) of IV provided by user. If ivSize is+*                       smaller than maximum IV size, the function will complete+*                       IV by random value.+*+* RETURN:+*       MV_OK   - Success+*       Other   - Fail+*+*******************************************************************************/+MV_STATUS   mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)+{+    MV_U8*  pSramIV;+#if defined(MV646xx)+    mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");+#endif+    pSramIV = cesaSramVirtPtr->cryptoIV;+    if(ivSize > MV_CESA_MAX_IV_LENGTH)+    {+        mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);+        ivSize = MV_CESA_MAX_IV_LENGTH;+    }+    if(pIV != NULL)+    {+        memcpy(pSramIV, pIV, ivSize);+        ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;+        pSramIV += ivSize;+    }++    while(ivSize > 0)+    {+        int size, mv_random = mvOsRand();++        size = MV_MIN(ivSize, sizeof(mv_random));+        memcpy(pSramIV, (void*)&mv_random, size);++        pSramIV += size;+        ivSize -= size;+    }+/*+    mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,+                                MV_CESA_MAX_IV_LENGTH);+    mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,+                              MV_CESA_MAX_IV_LENGTH);+*/+    return MV_OK;+}++/*******************************************************************************+* mvCesaSessionOpen - Open new uni-directional crypto session+*+* DESCRIPTION:+*       This function open new session.+*+* INPUT:+*       MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters+*+* OUTPUT:+*       short           *pSid  - session ID, should be used for all future+*                                   requests over this session.+*+* RETURN:+*       MV_OK           - Session opend successfully.+*       MV_FULL         - All sessions are in use, no free place in+*                       SA database.+*       MV_BAD_PARAM    - One of session input parameters is invalid.+*+*******************************************************************************/+MV_STATUS   mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)+{+    short       sid;+    MV_U32      config = 0;+    int         digestSize;++    cesaStats.openedCount++;+    +    /* Find free entry in SAD */+    for(sid=0; sid<cesaMaxSA; sid++)+    {+        if(pCesaSAD[sid].valid == 0)+        {+            break;+        }+    }+    if(sid == cesaMaxSA)+    {+        mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");+        return MV_FULL;+    }++    /* Check Input parameters for Open session */+    if (pSession->operation >= MV_CESA_MAX_OPERATION)+    {+        mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",+                    pSession->operation);+        return MV_BAD_PARAM;+    }+    config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);++    if( (pSession->direction != MV_CESA_DIR_ENCODE) &&+        (pSession->direction != MV_CESA_DIR_DECODE) )+    {+        mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",+                    pSession->direction);+        return MV_BAD_PARAM;+    }+    config |= (pSession->direction << MV_CESA_DIRECTION_BIT);+    /* Clear SA entry */+    /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */++    /* Check AUTH parameters and update SA entry */+    if(pSession->operation != MV_CESA_CRYPTO_ONLY)+    {+        /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */+        if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||+            (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )+        {+            if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)+            {+                mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",+                            pSession->macKeyLength);+                return MV_BAD_PARAM;+            }+            mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,+                            pCesaSAD[sid].pSramSA->macInnerIV, +                            pCesaSAD[sid].pSramSA->macOuterIV);+            pCesaSAD[sid].macKeyLength = pSession->macKeyLength;+        }+        switch(pSession->macMode)+        {+            case MV_CESA_MAC_MD5:+            case MV_CESA_MAC_HMAC_MD5:+                digestSize = MV_CESA_MD5_DIGEST_SIZE;+                break;++            case MV_CESA_MAC_SHA1:+            case MV_CESA_MAC_HMAC_SHA1:+                digestSize = MV_CESA_SHA1_DIGEST_SIZE;+                break;++            default:+                mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",+                            pSession->macMode);+                return MV_BAD_PARAM;+        }+        config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);++        /* Supported digest sizes: MD5 - 16 bytes (128 bits), */+        /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */+        if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))+        {+            mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",+                        pSession->digestSize);+            mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");+            return MV_BAD_PARAM;+        }+        pCesaSAD[sid].digestSize = pSession->digestSize;++        if(pCesaSAD[sid].digestSize == 12)+        {+            /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */+            config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);+        }+    }++    /* Check CRYPTO parameters and update SA entry */+    if(pSession->operation != MV_CESA_MAC_ONLY)+    {+        switch(pSession->cryptoAlgorithm)+        {+            case MV_CESA_CRYPTO_DES:+                pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;+                pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;+                break;++            case MV_CESA_CRYPTO_3DES:+                pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;+                pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;+                /* Only EDE mode is supported */+                config |= (MV_CESA_CRYPTO_3DES_EDE <<+                            MV_CESA_CRYPTO_3DES_MODE_BIT);+                break;++            case MV_CESA_CRYPTO_AES:+                switch(pSession->cryptoKeyLength)+                {+                    case 16:+                        pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;+                        config |= (MV_CESA_CRYPTO_AES_KEY_128 <<+                                       MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);+                        break;++                    case 24:+                        pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;+                        config |= (MV_CESA_CRYPTO_AES_KEY_192 <<+                                       MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);+                        break;++                    case 32:+                    default:+                        pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;+                        config |= (MV_CESA_CRYPTO_AES_KEY_256 <<+                                       MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);+                        break;+                }+                pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;+                break;++            default:+                mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",+                            pSession->cryptoAlgorithm);+                return MV_BAD_PARAM;+        }+        config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);++        if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)+        {+            mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",+                        pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);+            return MV_BAD_PARAM;+        }+        +        /* Copy Crypto key */+        if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&+            (pSession->direction == MV_CESA_DIR_DECODE))+        {+            /* Crypto Key for AES decode is computed from original key material */+            /* and depend on cryptoKeyLength (128/192/256 bits) */+            aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey, +                        pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);+        }+        else+        {+                /*panic("mvCesaSessionOpen2");*/+                memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey, +                    pCesaSAD[sid].cryptoKeyLength);+            +        }+        +        switch(pSession->cryptoMode)+        {+            case MV_CESA_CRYPTO_ECB:+                pCesaSAD[sid].cryptoIvSize = 0;+                break;++            case MV_CESA_CRYPTO_CBC:+                pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;+                break;++            case MV_CESA_CRYPTO_CTR:+                /* Supported only for AES algorithm */+                if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)+                {+                    mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");+                    return MV_BAD_PARAM;+                }+                pCesaSAD[sid].cryptoIvSize = 0;+                pCesaSAD[sid].ctrMode = 1;+                /* Replace to ECB mode for HW */+                pSession->cryptoMode = MV_CESA_CRYPTO_ECB;+                break;++            default:+                mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",+                            pSession->cryptoMode);+                return MV_BAD_PARAM;+        }+        +        config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);+    }+    pCesaSAD[sid].config = config;+    +    mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));+    if(pSid != NULL)+        *pSid = sid;++    pCesaSAD[sid].valid = 1;+    return MV_OK;+}++/*******************************************************************************+* mvCesaSessionClose - Close active crypto session+*+* DESCRIPTION:+*       This function closes existing session+*+* INPUT:+*       short sid   - Unique identifier of the session to be closed+*+* RETURN:+*       MV_OK        - Session closed successfully.+*       MV_BAD_PARAM - Session identifier is out of valid range.+*       MV_NOT_FOUND - There is no active session with such ID.+*+*******************************************************************************/+MV_STATUS mvCesaSessionClose(short sid)+{+    cesaStats.closedCount++;++    if(sid >= cesaMaxSA)+    {+        mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);+        return MV_BAD_PARAM;+    }+    if(pCesaSAD[sid].valid == 0)+    {+        mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);+        return MV_NOT_FOUND;+    }+    if(cesaLastSid == sid)+        cesaLastSid = -1;++    pCesaSAD[sid].valid = 0;+    return MV_OK;+}++/*******************************************************************************+* mvCesaAction - Perform crypto operation+*+* DESCRIPTION:+*       This function set new CESA request FIFO queue for further HW processing.+*       The function checks request parameters before set new request to the queue.+*       If one of the CESA channels is ready for processing the request will be+*       passed to HW. When request processing is finished the CESA interrupt will+*       be generated by HW. The caller should call mvCesaReadyGet() function to+*       complete request processing and get result.+*+* INPUT:+*       MV_CESA_COMMAND *pCmd   - pointer to new CESA request.+*                               It includes pointers to Source and Destination+*                               buffers, session identifier get from+*                               mvCesaSessionOpen() function, pointer to caller+*                               private data and all needed crypto parameters.+*+* RETURN:+*       MV_OK             - request successfully added to request queue+*                         and will be processed.+*       MV_NO_MORE        - request successfully added to request queue and will+*                         be processed, but request queue became Full and next+*                         request will not be accepted.+*       MV_NO_RESOURCE    - request queue is FULL and the request can not+*                         be processed.+*       MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is+*                         failed. Request can not be processed.+*       MV_NOT_ALLOWED    - This mixed request (CRYPTO+MAC) can not be processed+*                         as one request and should be splitted for two requests:+*                         CRYPTO_ONLY and MAC_ONLY.+*       MV_BAD_PARAM      - One of the request parameters is out of valid range.+*                         The request can not be processed.+*+*******************************************************************************/+MV_STATUS   mvCesaAction (MV_CESA_COMMAND *pCmd)+{+    MV_STATUS       status;+    MV_CESA_REQ*    pReq = pCesaReqEmpty;+    int             sid = pCmd->sessionId;+    MV_CESA_SA*     pSA = &pCesaSAD[sid];+#if (MV_CESA_VERSION >= 3)+     MV_CESA_REQ*   pFromReq;+     MV_CESA_REQ*   pToReq;+#endif+    cesaStats.reqCount++;++    /* Check that the request queue is not FULL */+    if(cesaReqResources == 0)+        return MV_NO_RESOURCE;++    if( (sid >= cesaMaxSA) || (!pSA->valid) )+    {+        mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);+        return MV_BAD_PARAM;+    }+    pSA->count++;++    if(pSA->ctrMode)+    {+        /* AES in CTR mode can't be mixed with Authentication */+        if( (pSA->config & MV_CESA_OPERATION_MASK) !=+            (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )+        {+            mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");+            return MV_NOT_ALLOWED;+        }+        /* All other request parameters should not be checked because key stream */+        /* (not user data) processed by AES HW engine */+        pReq->pOrgCmd = pCmd;+        /* Allocate temporary pCmd structure for Key stream */+        pCmd = mvCesaCtrModeInit();+        if(pCmd == NULL)+            return MV_OUT_OF_CPU_MEM;++        /* Prepare Key stream */+        mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);+        pReq->fixOffset = 0;+    }+    else+    {+        /* Check request parameters and calculae fixOffset */+        status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);+        if(status != MV_OK)+        {+            return status;+        }+    }+    pReq->pCmd = pCmd;++    /* Check if the packet need fragmentation */+    if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )+    {+        /* request size is smaller than single buffer size */+        pReq->fragMode = MV_CESA_FRAG_NONE;++        /* Prepare NOT fragmented packets */+        status = mvCesaReqProcess(pReq);+        if(status != MV_OK)+        {+            mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",+                        pReq, status);+        }+#if (MV_CESA_VERSION >= 3)+	pReq->frags.numFrag = 1;+#endif+    }+    else+    {+        MV_U8     frag = 0;++        /* request size is larger than buffer size - needs fragmentation */++        /* Check restrictions for processing fragmented packets */+        status = mvCesaFragParamCheck(pSA, pCmd);+        if(status != MV_OK)+            return status;++        pReq->fragMode = MV_CESA_FRAG_FIRST;+        pReq->frags.nextFrag = 0;++        /* Prepare Process Fragmented packets */+        while(pReq->fragMode != MV_CESA_FRAG_LAST)+        {+            if(frag >= MV_CESA_MAX_REQ_FRAGS)+            {+                mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);+                return MV_OUT_OF_CPU_MEM;+            }+            status = mvCesaFragReqProcess(pReq, frag);+            if(status == MV_OK) {+#if (MV_CESA_VERSION >= 3)+		if(frag) {+			pReq->dma[frag-1].pDmaLast->phyNextDescPtr = +				MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));+			mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));+		}+#endif+                frag++;+        }+        }+        pReq->frags.numFrag = frag;+#if (MV_CESA_VERSION >= 3)+	if(chainReqNum) {	+		chainReqNum += pReq->frags.numFrag;+		if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)+			chainReqNum = MAX_CESA_CHAIN_LENGTH;+	}		+#endif+    }++    pReq->state = MV_CESA_PENDING;++    pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);+    cesaReqResources -= 1;++/* #ifdef CESA_DEBUG */+    if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)+        cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);+/* #endif CESA_DEBUG */++    cesaLastSid = sid;++#if (MV_CESA_VERSION >= 3)+    /* Are we within chain bounderies and follows the first request ? */+    if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {+	if(chainIndex) {+		pFromReq = MV_CESA_REQ_PREV_PTR(pReq); +		pToReq = pReq;+		pReq->state = MV_CESA_CHAIN;+		/* assume concatenating is possible */+		pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr = +			MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));+		mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));+			+		/* align active & next pointers */+		if(pNextActiveChain->state != MV_CESA_PENDING)+			pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);+	}+	else { /* we have only one chain, start new one */+		chainReqNum = 0;+		chainIndex++;+		/* align active & next pointers  */+		if(pNextActiveChain->state != MV_CESA_PENDING)+			pEndCurrChain = pNextActiveChain = pReq;+	}+    }+    else {+		/* In case we concatenate full chain */+		if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {+			chainIndex++;+			if(pNextActiveChain->state != MV_CESA_PENDING)+				pEndCurrChain = pNextActiveChain = pReq;+			chainReqNum = 0;+		}+		+		pReq = pCesaReqProcess;+		if(pReq->state == MV_CESA_PENDING) {+			pNextActiveChain = pReq;+			pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);+        		/* Start Process new request */+ 	      		mvCesaReqProcessStart(pReq);+    		}+    }++    chainReqNum++;++    if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))+	cesaStats.maxChainUsage = chainReqNum;++#else++    /* Check status of CESA channels and process requests if possible */+    pReq = pCesaReqProcess;+    if(pReq->state == MV_CESA_PENDING)+    {+        /* Start Process new request */+        mvCesaReqProcessStart(pReq);+    }+#endif+    /* If request queue became FULL - return MV_NO_MORE */+    if(cesaReqResources == 0)+        return MV_NO_MORE;++    return MV_OK;++}++/*******************************************************************************+* mvCesaReadyGet - Get crypto request that processing is finished+*+* DESCRIPTION:+*       This function complete request processing and return ready request to+*       caller. To don't miss interrupts the caller must call this function+*       while MV_OK or MV_TERMINATE values returned.+*+* INPUT:+*   MV_U32          chanMap  - map of CESA channels finished thier job+*                              accordingly with CESA Cause register.+*   MV_CESA_RESULT* pResult  - pointer to structure contains information+*                            about ready request. It includes pointer to+*                            user private structure "pReqPrv", session identifier+*                            for this request "sessionId" and return code.+*                            Return code set to MV_FAIL if calculated digest value+*                            on decode direction is different than digest value+*                            in the packet.+*+* RETURN:+*       MV_OK           - Success, ready request is returned.+*       MV_NOT_READY    - Next request is not ready yet. New interrupt will+*                       be generated for futher request processing.+*       MV_EMPTY        - There is no more request for processing.+*       MV_BUSY         - Fragmented request is not ready yet.+*       MV_TERMINATE    - Call this function once more to complete processing+*                       of fragmented request.+*+*******************************************************************************/+MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)+{+    MV_STATUS       status, readyStatus = MV_NOT_READY;+    MV_U32          statusReg;+    MV_CESA_REQ*    pReq;+    MV_CESA_SA*     pSA;++#if (MV_CESA_VERSION >= 3)+    if(isFirstReq == MV_TRUE) {+	if(chainIndex == 0)+		chainReqNum = 0;+	+	isFirstReq = MV_FALSE;++	if(pNextActiveChain->state == MV_CESA_PENDING) {+		/* Start request Process */+		mvCesaReqProcessStart(pNextActiveChain);+		pEndCurrChain = pNextActiveChain;+		if(chainIndex > 0)+			chainIndex--;+		/* Update pNextActiveChain to next chain head */+		   while(pNextActiveChain->state == MV_CESA_CHAIN)+			pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);+    	}    +    }+    +    /* Check if there are more processed requests - can we remove pEndCurrChain ??? */+    if(pCesaReqProcess == pEndCurrChain) {+		isFirstReq = MV_TRUE;+		pEndCurrChain = pNextActiveChain;+#else+    if(pCesaReqProcess->state != MV_CESA_PROCESS) {+#endif+        return MV_EMPTY;+    }++#ifdef CESA_DEBUG+    statusReg = MV_REG_READ(MV_CESA_STATUS_REG);+    if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )+    {+        mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);+        cesaStats.notReadyCount++;+        return MV_NOT_READY;+    }+#endif /* CESA_DEBUG */++    cesaStats.readyCount++;++    pReq = pCesaReqProcess;+    pSA = &pCesaSAD[pReq->pCmd->sessionId];++    pResult->retCode = MV_OK;+    if(pReq->fragMode != MV_CESA_FRAG_NONE)+    {+        MV_U8*          pNewDigest;+      int             frag;+#if (MV_CESA_VERSION >= 3)+      pReq->frags.nextFrag = 1;+      while(pReq->frags.nextFrag <= pReq->frags.numFrag) {+#endif+	frag = (pReq->frags.nextFrag - 1);++        /* Restore DMA descriptor list */+        pReq->dma[frag].pDmaLast->phyNextDescPtr = +                MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));+        pReq->dma[frag].pDmaLast = NULL;++        /* Special processing for finished fragmented request */+        if(pReq->frags.nextFrag >= pReq->frags.numFrag)+        {+            mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);++            /* Fragmented packet is ready */+            if( (pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )+            {+                int  macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;++                if(macDataSize != 0)+                {+                    /* Calculate all other blocks by SW */+                    mvCesaFragAuthComplete(pReq, pSA, macDataSize);+                }++                /* Copy new digest from SRAM to the Destination buffer */+                pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;+                status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,+                                   pReq->pCmd->digestOffset, pSA->digestSize);++                /* For decryption: Compare new digest value with original one */+                if((pSA->config & MV_CESA_DIRECTION_MASK) ==+                            (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))+                {+                    if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)+                    {+/*+                        mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",+                            chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));+*/+                        /* Signiture verification is failed */+                        pResult->retCode = MV_FAIL;+                    }+                }+            }+            readyStatus = MV_OK;+        }+#if (MV_CESA_VERSION >= 3)+	pReq->frags.nextFrag++;+      }+#endif+    }+    else+    {+        mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);++        /* Restore DMA descriptor list */+        pReq->dma[0].pDmaLast->phyNextDescPtr = +                MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));+        pReq->dma[0].pDmaLast = NULL;+        if( ((pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&+            ((pSA->config & MV_CESA_DIRECTION_MASK) ==+                        (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )+        {+            /* For AUTH on decode : Check Digest result in Status register */+            statusReg = MV_REG_READ(MV_CESA_STATUS_REG);+            if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)+            {+/*+                mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",+                        chan, statusReg);+*/+                /* Signiture verification is failed */+                pResult->retCode = MV_FAIL;+            }+        }+        readyStatus = MV_OK;+    }++    if(readyStatus == MV_OK)+    {+        /* If Request is ready - Prepare pResult structure */+        pResult->pReqPrv = pReq->pCmd->pReqPrv;+        pResult->sessionId = pReq->pCmd->sessionId;++        pReq->state = MV_CESA_IDLE;+        pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);+        cesaReqResources++;++        if(pSA->ctrMode)+        {+            /* For AES CTR mode - complete processing and free allocated resources */+            mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);+            mvCesaCtrModeFinish(pReq->pCmd);+            pReq->pOrgCmd = NULL;+        }+    }++#if (MV_CESA_VERSION < 3)+    if(pCesaReqProcess->state == MV_CESA_PROCESS)+    {+        /* Start request Process */+        mvCesaReqProcessStart(pCesaReqProcess);+        if(readyStatus == MV_NOT_READY)+            readyStatus = MV_BUSY;+    }+    else if(pCesaReqProcess != pCesaReqEmpty)+    {+        /* Start process new request from the queue */+        mvCesaReqProcessStart(pCesaReqProcess);+    }+#endif +    return readyStatus;+}++/***************** Functions to work with CESA_MBUF structure ******************/++/*******************************************************************************+* mvCesaMbufOffset - Locate offset in the Mbuf structure+*+* DESCRIPTION:+*       This function locates offset inside Multi-Bufeer structure.+*       It get fragment number and place in the fragment where the offset+*       is located.+*+*+* INPUT:+*   MV_CESA_MBUF* pMbuf  - Pointer to multi-buffer structure+*   int           offset - Offset from the beginning of the data presented by+*                        the Mbuf structure.+*+* OUTPUT:+*   int*        pBufOffset  - Offset from the beginning of the fragment where+*                           the offset is located.+*+* RETURN:+*       int - Number of fragment, where the offset is located\+*+*******************************************************************************/+int     mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)+{+    int frag = 0;++    while(offset > 0)+    {+        if(frag >= pMbuf->numFrags)+        {+            mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",+                    frag, pMbuf->numFrags);+            return MV_INVALID;+        }+        if(offset < pMbuf->pFrags[frag].bufSize)+        {+            break;+        }+        offset -= pMbuf->pFrags[frag].bufSize;+        frag++;+    }+    if(pBufOffset != NULL)+        *pBufOffset = offset;++    return frag;+}++/*******************************************************************************+* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer+*+* DESCRIPTION:+*+*+* INPUT:+*   MV_U8*          pDstBuf  - Pointer to continuous buffer, where data is+*                              copied to.+*   MV_CESA_MBUF*   pSrcMbuf - Pointer to multi-buffer structure where data is+*                              copied from.+*   int             offset   - Offset in the Mbuf structure where located first+*                            byte of data should be copied.+*   int             size     - Size of data should be copied+*+* RETURN:+*       MV_OK           - Success, all data is copied successfully.+*       MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.+*                         No data is copied.+*       MV_EMPTY        - Multi-buffer structure has not enough data to copy+*                       Data from the offset to end of Mbuf data is copied.+*+*******************************************************************************/+MV_STATUS   mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,+                               int offset, int size)+{+    int     frag, fragOffset, bufSize;+    MV_U8*  pBuf;++    if(size == 0)+        return MV_OK;++    frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);+    if(frag == MV_INVALID)+    {+        mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);+        return MV_OUT_OF_RANGE;+    }++    bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;+    pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;+    while(MV_TRUE)+    {+        if(size <= bufSize)+        {+            memcpy(pDstBuf, pBuf, size);+            return MV_OK;+        }+        memcpy(pDstBuf, pBuf, bufSize);+        size -= bufSize;+        frag++;+        pDstBuf += bufSize;+        if(frag >= pSrcMbuf->numFrags)+            break;++        bufSize = pSrcMbuf->pFrags[frag].bufSize;+        pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;+    }+    mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",+                size);+    return MV_EMPTY;+}++/*******************************************************************************+* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure+*+* DESCRIPTION:+*+*+* INPUT:+*   MV_U8*          pSrcBuf  - Pointer to continuous buffer, where data is+*                              copied from.+*   MV_CESA_MBUF*   pDstMbuf - Pointer to multi-buffer structure where data is+*                              copied to.+*   int             offset   - Offset in the Mbuf structure where located first+*                            byte of data should be copied.+*   int             size     - Size of data should be copied+*+* RETURN:+*       MV_OK           - Success, all data is copied successfully.+*       MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.+*                         No data is copied.+*       MV_FULL         - Multi-buffer structure has not enough place to copy+*                       all data. Data from the offset to end of Mbuf data+*                       is copied.+*+*******************************************************************************/+MV_STATUS   mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,+                               int offset, int size)+{+    int     frag, fragOffset, bufSize;+    MV_U8*  pBuf;++    if(size == 0)+        return MV_OK;++    frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);+    if(frag == MV_INVALID)+    {+        mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);+        return MV_OUT_OF_RANGE;+    }++    bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;+    pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;+    while(MV_TRUE)+    {+        if(size <= bufSize)+        {+            memcpy(pBuf, pSrcBuf, size);+            return MV_OK;+        }+        memcpy(pBuf, pSrcBuf, bufSize);+        size -= bufSize;+        frag++;+        pSrcBuf += bufSize;+        if(frag >= pDstMbuf->numFrags)+            break;++        bufSize = pDstMbuf->pFrags[frag].bufSize;+        pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;+    }+    mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",+                size);+    return MV_FULL;+}++/*******************************************************************************+* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure+*+* DESCRIPTION:+*+*+* INPUT:+*+*   MV_CESA_MBUF*   pDstMbuf - Pointer to multi-buffer structure where data is+*                              copied to.+*   int      dstMbufOffset   - Offset in the dstMbuf structure where first byte+*                            of data should be copied to.+*   MV_CESA_MBUF*   pSrcMbuf - Pointer to multi-buffer structure where data is+*                              copied from.+*   int      srcMbufOffset   - Offset in the srcMbuf structure where first byte+*                            of data should be copied from.+*   int             size     - Size of data should be copied+*+* RETURN:+*       MV_OK           - Success, all data is copied successfully.+*       MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of+*                       srcMbuf or dstMbuf structure correspondently.+*                       No data is copied.+*       MV_BAD_SIZE     - srcMbuf or dstMbuf structure is too small to copy+*                       all data. Partial data is copied+*+*******************************************************************************/+MV_STATUS   mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,+                           MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)+{+    int     srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;+    int     copySize;+    MV_U8   *pSrc, *pDst;++    if(size == 0)+        return MV_OK;++    srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);+    if(srcFrag == MV_INVALID)+    {+        mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);+        return MV_OUT_OF_RANGE;+    }+    pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;+    srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;++    dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);+    if(dstFrag == MV_INVALID)+    {+        mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);+        return MV_OUT_OF_RANGE;+    }+    pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;+    dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;++    while(size > 0)+    {+        copySize = MV_MIN(srcSize, dstSize);+        if(size <= copySize)+        {+            memcpy(pDst, pSrc, size);+            return MV_OK;+        }+        memcpy(pDst, pSrc, copySize);+        size -= copySize;+        srcSize -= copySize;+        dstSize -= copySize;++        if(srcSize == 0)+        {+            srcFrag++;+            if(srcFrag >= pMbufSrc->numFrags)+                break;++            pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;+            srcSize = pMbufSrc->pFrags[srcFrag].bufSize;+        }++        if(dstSize == 0)+        {+            dstFrag++;+            if(dstFrag >= pMbufDst->numFrags)+                break;++            pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;+            dstSize = pMbufDst->pFrags[dstFrag].bufSize;+        }+    }+    mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",+                size);++    return MV_BAD_SIZE;+}++static MV_STATUS   mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)+{+    int     frag, fragOffset, bufSize;+    MV_U8*  pBuf;++    if(size == 0)+        return MV_OK;++    frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);+    if(frag == MV_INVALID)+    {+        mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);+        return MV_OUT_OF_RANGE;+    }++    bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;+    pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;+    while(MV_TRUE)+    {+        if(size <= bufSize)+        {+            mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);+            return MV_OK;+        }++        mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);+        size -= bufSize;+        frag++;+        if(frag >= pMbuf->numFrags)+            break;++        bufSize = pMbuf->pFrags[frag].bufSize;+        pBuf = pMbuf->pFrags[frag].bufVirtPtr;+    }+    mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",+                __FUNCTION__, size);+    return MV_FULL;+}+++/*************************************** Local Functions ******************************/++/*******************************************************************************+* mvCesaFragReqProcess - Process fragmented request+*+* DESCRIPTION:+*       This function processes a fragment of fragmented request (First, Middle or Last)+*+*+* INPUT:+*       MV_CESA_REQ* pReq   - Pointer to the request in the request queue.+*+* RETURN:+*       MV_OK        - The fragment is successfully passed to HW for processing.+*       MV_TERMINATE - Means, that HW finished its work on this packet and no more+*                    interrupts will be generated for this request.+*                    Function mvCesaReadyGet() must be called to complete request+*                    processing and get request result.+*+*******************************************************************************/+static MV_STATUS   mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)+{+    int                     i, copySize, cryptoDataSize, macDataSize, sid;+    int                     cryptoIvOffset, digestOffset;+    MV_U32                  config;+    MV_CESA_COMMAND*        pCmd = pReq->pCmd;+    MV_CESA_SA*             pSA;+    MV_CESA_MBUF*           pMbuf;+    MV_DMA_DESC*            pDmaDesc = pReq->dma[frag].pDmaFirst;+    MV_U8*                  pSramBuf = cesaSramVirtPtr->buf;+    int                     macTotalLen = 0;+    int                     fixOffset, cryptoOffset, macOffset;++    cesaStats.fragCount++;++    sid = pReq->pCmd->sessionId;++    pSA = &pCesaSAD[sid];++    cryptoIvOffset = digestOffset = 0;+    i = macDataSize = 0;+    cryptoDataSize = 0;++    /* First fragment processing */+    if(pReq->fragMode == MV_CESA_FRAG_FIRST)+    {+        /* pReq->frags monitors processing of fragmented request between fragments */+        pReq->frags.bufOffset = 0;+        pReq->frags.cryptoSize = 0;+        pReq->frags.macSize = 0;++        config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);++        /* fixOffset can be not equal to zero only for FIRST fragment */+        fixOffset = pReq->fixOffset;+        /* For FIRST fragment crypto and mac offsets are taken from pCmd */+        cryptoOffset = pCmd->cryptoOffset;+        macOffset = pCmd->macOffset;++        copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;++        /* Find fragment size: Must meet all requirements for CRYPTO and MAC+         * cryptoDataSize   - size of data will be encrypted/decrypted in this fragment+         * macDataSize      - size of data will be signed/verified in this fragment+         * copySize         - size of data will be copied from srcMbuf to SRAM and+         *                  back to dstMbuf for this fragment+         */+        mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,+                        ©Size, &cryptoDataSize, &macDataSize);++        if( (pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))+        {+            /* CryptoIV special processing */+            if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==+                (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )+            {+                /* In CBC mode for encode direction when IV from user */+                if( (pCmd->ivFromUser) &&+                    ((pSA->config & MV_CESA_DIRECTION_MASK) ==+                        (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )+                {++                    /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,+                    * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place+                    * in the buffer to SRAM IVPointer+                    */+                    i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],+                                    MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);+                }++                /* Special processing when IV is not located in the first fragment */+                if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))+                {+                    /* Prepare dummy place for cryptoIV in SRAM */+                    cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();++                    /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */+                    if((pSA->config & MV_CESA_DIRECTION_MASK) ==+                            (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))+                    {+                        i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],+                                    MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);+                    }+                    else+                    {+                        /* For Encryption when IV is NOT from User: */+                        /* Copy IV from SRAM to buffer (pCmd->ivOffset) */+                        if(pCmd->ivFromUser == 0)+                        {+                            /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */+                            i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],+                                    MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);+                        }+                    }+                }+                else+                {+                    cryptoIvOffset = pCmd->ivOffset;+                }+            }+        }++        if( (pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )+        {+            /* MAC digest special processing on Decode direction */+            if((pSA->config & MV_CESA_DIRECTION_MASK) ==+                        (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))+            {+                /* Save digest from pCmd->digestOffset */+                mvCesaCopyFromMbuf(pReq->frags.orgDigest,+                               pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);++                /* If pCmd->digestOffset is not located on the first */+                if(pCmd->digestOffset > (copySize - pSA->digestSize))+                {+                    MV_U8  digestZero[MV_CESA_MAX_DIGEST_SIZE];++                    /* Set zeros to pCmd->digestOffset (DRAM) */+                    memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);+                    mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);++                    /* Prepare dummy place for digest in SRAM */+                    digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();+                }+                else+                {+                    digestOffset = pCmd->digestOffset;+                }+            }+        }+        /* Update SA in SRAM */+        if(cesaLastSid != sid)+        {+            mvCesaSramSaUpdate(sid, &pDmaDesc[i]);+            i++;+        }++        pReq->fragMode = MV_CESA_FRAG_MIDDLE;+    }+    else+    {+        /* Continue fragment */+        fixOffset = 0;+        cryptoOffset = 0;+        macOffset = 0;+        if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))+        {+            /* Last fragment */+            config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);+            pReq->fragMode = MV_CESA_FRAG_LAST;+            copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;++            if( (pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )+            {+                macDataSize = pCmd->macLength - pReq->frags.macSize;++                /* If pCmd->digestOffset is not located on last fragment */+                if(pCmd->digestOffset < pReq->frags.bufOffset)+                {+                    /* Prepare dummy place for digest in SRAM */+                    digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();+                }+                else+                {+                    digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;+                }+                pReq->frags.newDigestOffset = digestOffset;+                macTotalLen = pCmd->macLength;++                /* HW can't calculate the Digest correctly for fragmented packets+                 * in the following cases:+                 *  - MV88F5182                                           ||+                 *  - MV88F5181L when total macLength more that 16 Kbytes ||+                 *  - total macLength more that 64 Kbytes+                 */+                if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||+                    ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&+                      (mvCtrlRevGet() >= MV_5181L_A0_REV)  &&+                      (pCmd->macLength >= (1 << 14)) ) )+                {+                    return MV_TERMINATE;+                }+            }+            if( (pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )+            {+                cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;+            }++            /* cryptoIvOffset - don't care */+        }+        else+        {+            /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */+            if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&+                (((pSA->config & MV_CESA_MAC_MODE_MASK) ==+                    (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||+                ((pSA->config & MV_CESA_MAC_MODE_MASK) ==+                    (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )+            {+                pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();+                pReq->fragMode = MV_CESA_FRAG_LAST;++                return MV_TERMINATE;+            }+            /* Middle fragment */+            config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);+            copySize = sizeof(cesaSramVirtPtr->buf);+            /* digestOffset and cryptoIvOffset - don't care */++            /* Find fragment size */+            mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,+                            ©Size, &cryptoDataSize, &macDataSize);+        }+    }+    /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/+    pMbuf = pCmd->pSrc;+    i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],+                                MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);++    /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */+    mvCesaSramDescrBuild(config, frag, +                cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,+                cryptoDataSize, macOffset + fixOffset,+                digestOffset + fixOffset, macDataSize, macTotalLen,+                pReq, &pDmaDesc[i]);+    i++;++   /* Add special descriptor Ownership for CPU */+    pDmaDesc[i].byteCnt = 0;+    pDmaDesc[i].phySrcAdd = 0;+    pDmaDesc[i].phyDestAdd = 0;+    i++;++    /********* Prepare DMA descriptors to copy from SRAM to pDst *********/+    pMbuf = pCmd->pDst;+    i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],+                                MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);++    /* Next field of Last DMA descriptor must be NULL */+    pDmaDesc[i-1].phyNextDescPtr = 0;+    pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];+    mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst, +                    i*sizeof(MV_DMA_DESC));++    /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/++    pReq->frags.bufOffset += copySize;+    pReq->frags.cryptoSize += cryptoDataSize;+    pReq->frags.macSize += macDataSize;++    return MV_OK;+}+++/*******************************************************************************+* mvCesaReqProcess - Process regular (Non-fragmented) request+*+* DESCRIPTION:+*       This function processes the whole (not fragmented) request+*+* INPUT:+*       MV_CESA_REQ* pReq   - Pointer to the request in the request queue.+*+* RETURN:+*       MV_OK   - The request is successfully passed to HW for processing.+*       Other   - Failure. The request will not be processed+*+*******************************************************************************/+static MV_STATUS   mvCesaReqProcess(MV_CESA_REQ* pReq)+{+    MV_CESA_MBUF    *pMbuf;+    MV_DMA_DESC     *pDmaDesc;+    MV_U8           *pSramBuf;+    int             sid, i, fixOffset;+    MV_CESA_SA      *pSA;+    MV_CESA_COMMAND *pCmd = pReq->pCmd;++    cesaStats.procCount++;++    sid = pCmd->sessionId;+    pSA = &pCesaSAD[sid];+    pDmaDesc = pReq->dma[0].pDmaFirst;+    pSramBuf = cesaSramVirtPtr->buf;+    fixOffset = pReq->fixOffset;++/*+    mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",+                sid, pSA, pDmaDesc, pSramBuf);+*/+    i = 0;++    /* Crypto IV Special processing in CBC mode for Encryption direction */+    if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&+        ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&+        ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&+        (pCmd->ivFromUser) )+    {+        /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,+         * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place+         * in the buffer to SRAM IVPointer+         */+        i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],+                                    MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);+    }++    /* Update SA in SRAM */+    if(cesaLastSid != sid)+    {+        mvCesaSramSaUpdate(sid, &pDmaDesc[i]);+        i++;+    }++    /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/+    pMbuf = pCmd->pSrc;+    i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],+                                MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);++    /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */+    mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset, +                        pCmd->ivOffset + fixOffset, pCmd->cryptoLength,+                        pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,+                        pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);+    i++;++   /* Add special descriptor Ownership for CPU */+    pDmaDesc[i].byteCnt = 0;+    pDmaDesc[i].phySrcAdd = 0;+    pDmaDesc[i].phyDestAdd = 0;+    i++;++    /********* Prepare DMA descriptors to copy from SRAM to pDst *********/+    pMbuf = pCmd->pDst;+    i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],+                                MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);++    /* Next field of Last DMA descriptor must be NULL */+    pDmaDesc[i-1].phyNextDescPtr = 0;+    pReq->dma[0].pDmaLast = &pDmaDesc[i-1];+    mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));+            +    return MV_OK;+}+++/*******************************************************************************+* mvCesaSramDescrBuild - Set CESA descriptor in SRAM+*+* DESCRIPTION:+*       This function builds CESA descriptor in SRAM from all Command parameters+*+*+* INPUT:+*       int     chan            - CESA channel uses the descriptor+*       MV_U32  config          - 32 bits of WORD_0 in CESA descriptor structure+*       int     cryptoOffset    - Offset from the beginning of SRAM buffer where+*                               data for encryption/decription is started.+*       int     ivOffset        - Offset of crypto IV from the SRAM base. Valid only+*                               for first fragment.+*       int     cryptoLength    - Size (in bytes) of data for encryption/descryption+*                               operation on this fragment.+*       int     macOffset       - Offset from the beginning of SRAM buffer where+*                               data for Authentication is started+*       int     digestOffset    - Offset from the beginning of SRAM buffer where+*                               digest is located. Valid for first and last fragments.+*       int     macLength       - Size (in bytes) of data for Authentication+*                               operation on this fragment.+*       int     macTotalLen     - Toatl size (in bytes) of data for Authentication+*                               operation on the whole request (packet). Valid for+*                               last fragment only.+*+* RETURN:   None+*+*******************************************************************************/+static void    mvCesaSramDescrBuild(MV_U32 config, int frag, +                             int cryptoOffset, int ivOffset, int cryptoLength,+                             int macOffset, int digestOffset, int macLength,+                             int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)+{    +    MV_CESA_DESC*   pCesaDesc = &pReq->pCesaDesc[frag];+    MV_CESA_DESC*   pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;+    MV_U16          sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());++    pCesaDesc->config = MV_32BIT_LE(config);++    if( (config & MV_CESA_OPERATION_MASK) !=+         (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )+    {+        /* word 1 */+        pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);+        pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);+        /* word 2 */+        pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);+        /* word 3 */+        pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey - +                                                            mvCesaSramAddrGet()));+        /* word 4 */+        pCesaDesc->cryptoIvOffset  = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -+                                                            mvCesaSramAddrGet()));+        pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);+    }++    if( (config & MV_CESA_OPERATION_MASK) !=+         (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )+    {+        /* word 5 */+        pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);+        pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);++        /* word 6 */+        pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);+        pCesaDesc->macDataLen = MV_16BIT_LE(macLength);++        /* word 7 */+        pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV - +                                 mvCesaSramAddrGet()));+        pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV - +                                 mvCesaSramAddrGet()));+    }+    /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */+    pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));+    pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));+    pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);+                                +    /* flush Source buffer */+    mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));+}++/*******************************************************************************+* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.+*+* DESCRIPTION:+*   Copy to SRAM values of the required SA.+*+*+* INPUT:+*       short       sid          - Session ID needs SRAM Cache update+*       MV_DMA_DESC *pDmaDesc   - Pointer to DMA descriptor used to+*                                copy SA values from DRAM to SRAM.+*+* RETURN:+*       MV_OK           - Cache entry for this SA copied to SRAM.+*       MV_NO_CHANGE    - Cache entry for this SA already exist in SRAM+*+*******************************************************************************/+static INLINE void   mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)+{+    MV_CESA_SA      *pSA = &pCesaSAD[sid];++    /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */+     pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);+    pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));+     pDmaDesc->phyDestAdd =+          MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));++    /* Source buffer is already flushed during OpenSession*/+    /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/+}++/*******************************************************************************+* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by+*                       Mbuf structure from DRAM to SRAM+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_MBUF*   pMbuf       - pointer to Mbuf structure contains request+*                                   data in DRAM+*       MV_U8*          pSramBuf    - pointer to buffer in SRAM where data should+*                                   be copied to.+*       MV_DMA_DESC*    pDmaDesc   - pointer to first DMA descriptor for this copy.+*                                   The function set number of DMA descriptors needed+*                                   to copy the copySize bytes from Mbuf.+*       MV_BOOL         isToMbuf    - Copy direction.+*                                   MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.+*                                   MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.+*       int             offset      - Offset in the Mbuf structure that copy should be+*                                   started from.+*       int             copySize    - Size of data should be copied.+*+* RETURN:+*       int  - number of DMA descriptors used for the copy.+*+*******************************************************************************/+#ifndef MV_NETBSD+static INLINE int    mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf, +                        MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,+                        int offset, int copySize, MV_BOOL skipFlush)+{+    int     bufOffset, bufSize, size, frag, i;+    MV_U8*  pBuf;++    i = 0;++    /* Calculate start place for copy: fragment number and offset in the fragment */+    frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);+    bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;+    pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;++    /* Size accumulate total copy size */+    size = 0;++    /* Create DMA lists to copy mBuf from pSrc to SRAM */+    while(size < copySize)+    {+        /* Find copy size for each DMA descriptor */+        bufSize = MV_MIN(bufSize, (copySize - size));+        pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);+        if(isToMbuf)+        {+            pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));+            pDmaDesc[i].phySrcAdd  =+                MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));+            /* invalidate the buffer */+	    if(skipFlush == MV_FALSE)+            	mvOsCacheInvalidate(NULL, pBuf, bufSize);+        }+        else+        {+            pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));+            pDmaDesc[i].phyDestAdd =+                MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));+            /* flush the buffer */+	    if(skipFlush == MV_FALSE)+            	mvOsCacheFlush(NULL, pBuf, bufSize);+        }++        /* Count number of used DMA descriptors */+        i++;+        size += bufSize;++        /* go to next fragment in the Mbuf */+        frag++;+        pBuf = pMbuf->pFrags[frag].bufVirtPtr;+        bufSize = pMbuf->pFrags[frag].bufSize;+    }+    return i;+}+#else /* MV_NETBSD */+static int    mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,+                        MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,+                        int offset, int copySize, MV_BOOL skipFlush)+{+	int bufOffset, bufSize, thisSize, size, frag, i;+	MV_ULONG bufPhys, sramPhys;+    MV_U8*  pBuf;++	/*+	 * Calculate start place for copy: fragment number and offset in+	 * the fragment+	 */+    frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);++	/*+	 * Get SRAM physical address only once. We can update it in-place+	 * as we build the descriptor chain.+	 */+	sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);++	/*+	 * 'size' accumulates total copy size, 'i' counts desccriptors.+	 */+	size = i = 0;++	/* Create DMA lists to copy mBuf from pSrc to SRAM */+	while (size < copySize) {+		/*+		 * Calculate # of bytes to copy from the current fragment,+		 * and the pointer to the start of data+		 */+    bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;+    pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;+		bufOffset = 0;	/* First frag may be non-zero */+		frag++;++		/*+		 * As long as there is data in the current fragment...+		 */+		while (bufSize > 0) {+			/*+			 * Ensure we don't cross an MMU page boundary.+			 * XXX: This is NetBSD-specific, but it is a+			 * quick and dirty way to fix the problem.+			 * A true HAL would rely on the OS-specific+			 * driver to do this...+			 */+			thisSize = PAGE_SIZE -+			    (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));+			thisSize = MV_MIN(bufSize, thisSize);+			/*+			 * Make sure we don't copy more than requested+			 */+			if (thisSize > (copySize - size)) {+				thisSize = copySize - size;+				bufSize = 0;+			}++			/*+			 * Physicall address of this fragment+			 */+			bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));++			/*+			 * Set up the descriptor+			 */+		        pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);+		        if(isToMbuf) {+				pDmaDesc[i].phyDestAdd = bufPhys;+				pDmaDesc[i].phySrcAdd  = MV_32BIT_LE(sramPhys);+            /* invalidate the buffer */+				if(skipFlush == MV_FALSE)+					mvOsCacheInvalidate(NULL, pBuf, thisSize);+			} else {+				pDmaDesc[i].phySrcAdd = bufPhys;+				pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);+            /* flush the buffer */+				if(skipFlush == MV_FALSE)+					mvOsCacheFlush(NULL, pBuf, thisSize);+			}++			pDmaDesc[i].phyNextDescPtr =+			    MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));++        /* flush the DMA desc */+        mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));++			/* Update state */+			bufSize -= thisSize;+			sramPhys += thisSize;+			pBuf += thisSize;+			size += thisSize;+        i++;+		}+	}++    return i;+}+#endif /* MV_NETBSD */+/*******************************************************************************+* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key+*+* DESCRIPTION:+*       This function calculate Inner and Outer values used for HMAC algorithm.+*       This operation allows improve performance fro the whole HMAC processing.+*+* INPUT:+*       MV_CESA_MAC_MODE    macMode     - Authentication mode: HMAC_MD5 or HMAC_SHA1.+*       unsigned char       key[]       - Pointer to HMAC key.+*       int                 keyLength   - Size of HMAC key (maximum 64 bytes)+*+* OUTPUT:+*       unsigned char       innerIV[]   - HASH(key^inner)+*       unsigned char       outerIV[]   - HASH(key^outter)+*+* RETURN:   None+*+*******************************************************************************/+static void    mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,+                     unsigned char innerIV[], unsigned char outerIV[])+{+    unsigned char   inner[MV_CESA_MAX_MAC_KEY_LENGTH];+    unsigned char   outer[MV_CESA_MAX_MAC_KEY_LENGTH];+    int             i, digestSize = 0;+#if defined(MV_CPU_LE) || defined(MV_PPC)+    MV_U32          swapped32, val32, *pVal32;+#endif +    for(i=0; i<keyLength; i++)+    {+        inner[i] = 0x36 ^ key[i];+        outer[i] = 0x5c ^ key[i];+    }++    for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)+    {+        inner[i] = 0x36;+        outer[i] = 0x5c;+    }+    if(macMode == MV_CESA_MAC_HMAC_MD5)+    {+        MV_MD5_CONTEXT  ctx;++        mvMD5Init(&ctx);+        mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);++        memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);+        memset(&ctx, 0, sizeof(ctx));++        mvMD5Init(&ctx);+        mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);+        memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);+        memset(&ctx, 0, sizeof(ctx));+        digestSize = MV_CESA_MD5_DIGEST_SIZE;+    }+    else if(macMode == MV_CESA_MAC_HMAC_SHA1)+    {+        MV_SHA1_CTX  ctx;++        mvSHA1Init(&ctx);+        mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);+        memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);+        memset(&ctx, 0, sizeof(ctx));++        mvSHA1Init(&ctx);+        mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);+        memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);+        memset(&ctx, 0, sizeof(ctx));+        digestSize = MV_CESA_SHA1_DIGEST_SIZE;+    }+    else+    {+        mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);+    }+#if defined(MV_CPU_LE) || defined(MV_PPC)+    /* 32 bits Swap of Inner and Outer values */+    pVal32 = (MV_U32*)innerIV;+    for(i=0; i<digestSize/4; i++)+    {+        val32 = *pVal32;+        swapped32 = MV_BYTE_SWAP_32BIT(val32);+        *pVal32 = swapped32;+        pVal32++;+    }+    pVal32 = (MV_U32*)outerIV;+    for(i=0; i<digestSize/4; i++)+    {+        val32 = *pVal32;+        swapped32 = MV_BYTE_SWAP_32BIT(val32);+        *pVal32 = swapped32;+        pVal32++;+    }+#endif  /* defined(MV_CPU_LE) || defined(MV_PPC) */+}+++/*******************************************************************************+* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_MBUF*   pMbuf           - Pointer to Mbuf structure where data+*                                       for SHA1 is placed.+*       int             offset          - Offset in the Mbuf structure where+*                                       unprocessed data for SHA1 is started.+*       MV_U8*          pOuterIV        - Pointer to OUTER for this session.+*                                       If pOuterIV==NULL - MAC mode is HASH_SHA1+*                                       If pOuterIV!=NULL - MAC mode is HMAC_SHA1+*       int             macLeftSize     - Size of unprocessed data for SHA1.+*       int             macTotalSize    - Total size of data for SHA1 in the+*                                       request (processed + unprocessed)+*+* OUTPUT:+*       MV_U8*     pDigest  - Pointer to place where calculated Digest will+*                           be stored.+*+* RETURN:   None+*+*******************************************************************************/+static void    mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,+                                      MV_U8* pOuterIV, int macLeftSize,+                                      int macTotalSize, MV_U8* pDigest)+{+    MV_SHA1_CTX     ctx;+    MV_U8           *pData;+    int             i, frag, fragOffset, size;++    /* Read temporary Digest from HW */+    for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)+    {+        ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));+    }+    /* Initialize MV_SHA1_CTX structure */+    memset(ctx.buffer, 0, 64);+    /* Set count[0] in bits. 32 bits is enough for 512 MBytes */+    /* so count[1] is always 0 */+    ctx.count[0] = ((macTotalSize - macLeftSize) * 8);+    ctx.count[1] = 0;++    /* If HMAC - add size of Inner block (64 bytes) ro count[0] */+    if(pOuterIV != NULL)+        ctx.count[0] += (64 * 8);++    /* Get place of unprocessed data in the Mbuf structure */+    frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);+    if(frag == MV_INVALID)+    {+        mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);+        return;+    }++    pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;+    size = pMbuf->pFrags[frag].bufSize - fragOffset;++    /* Complete Inner part */+    while(macLeftSize > 0)+    {+        if(macLeftSize <= size)+        {+            mvSHA1Update(&ctx, pData, macLeftSize);+            break;+        }+        mvSHA1Update(&ctx, pData, size);+        macLeftSize -= size;+        frag++;+        pData = pMbuf->pFrags[frag].bufVirtPtr;+        size = pMbuf->pFrags[frag].bufSize;+    }+    mvSHA1Final(pDigest, &ctx);+/*+    mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",+                pOuterIV, macLeftSize, macTotalSize);+    mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);+*/++    if(pOuterIV != NULL)+    {+        /* If HMAC - Complete Outer part */+        for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)+        {+#if defined(MV_CPU_LE) || defined(MV_ARM)+            ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);+#else+	    ctx.state[i] = ((MV_U32*)pOuterIV)[i];+#endif+	}+        memset(ctx.buffer, 0, 64);++        ctx.count[0] = 64*8;+        ctx.count[1] = 0;+        mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);+        mvSHA1Final(pDigest, &ctx);+    }+}++/*******************************************************************************+* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_MBUF*   pMbuf           - Pointer to Mbuf structure where data+*                                       for SHA1 is placed.+*       int             offset          - Offset in the Mbuf structure where+*                                       unprocessed data for MD5 is started.+*       MV_U8*          pOuterIV        - Pointer to OUTER for this session.+*                                       If pOuterIV==NULL - MAC mode is HASH_MD5+*                                       If pOuterIV!=NULL - MAC mode is HMAC_MD5+*       int             macLeftSize     - Size of unprocessed data for MD5.+*       int             macTotalSize    - Total size of data for MD5 in the+*                                       request (processed + unprocessed)+*+* OUTPUT:+*       MV_U8*     pDigest  - Pointer to place where calculated Digest will+*                           be stored.+*+* RETURN:   None+*+*******************************************************************************/+static void    mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,+                                     MV_U8* pOuterIV, int macLeftSize,+                                     int macTotalSize, MV_U8* pDigest)+{+    MV_MD5_CONTEXT  ctx;+    MV_U8           *pData;+    int             i, frag, fragOffset, size;++    /* Read temporary Digest from HW */+    for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)+    {+        ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));+    }+    memset(ctx.in, 0, 64);++    /* Set count[0] in bits. 32 bits is enough for 512 MBytes */+    /* so count[1] is always 0 */+    ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);+    ctx.bits[1] = 0;++    /* If HMAC - add size of Inner block (64 bytes) ro count[0] */+    if(pOuterIV != NULL)+        ctx.bits[0] += (64 * 8);++    frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);+    if(frag == MV_INVALID)+    {+        mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);+        return;+    }++    pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;+    size = pMbuf->pFrags[frag].bufSize - fragOffset;++    /* Complete Inner part */+    while(macLeftSize > 0)+    {+        if(macLeftSize <= size)+        {+            mvMD5Update(&ctx, pData, macLeftSize);+            break;+        }+        mvMD5Update(&ctx, pData, size);+        macLeftSize -= size;+        frag++;+        pData = pMbuf->pFrags[frag].bufVirtPtr;+        size = pMbuf->pFrags[frag].bufSize;+    }+    mvMD5Final(pDigest, &ctx);++/*+    mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",+                pOuterIV, macLeftSize, macTotalSize);+    mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);+*/+    if(pOuterIV != NULL)+    {+        /* Complete Outer part */+        for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)+        {+#if defined(MV_CPU_LE) || defined(MV_ARM)+            ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);+#else+	    ctx.buf[i] = ((MV_U32*)pOuterIV)[i];+#endif+	}+        memset(ctx.in, 0, 64);++        ctx.bits[0] = 64*8;+        ctx.bits[1] = 0;+        mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);+        mvMD5Final(pDigest, &ctx);+    }+}++/*******************************************************************************+* mvCesaFragAuthComplete -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_REQ*    pReq,+*       MV_CESA_SA*     pSA,+*       int             macDataSize+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static MV_STATUS   mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,+                               int macDataSize)+{+    MV_CESA_COMMAND*        pCmd = pReq->pCmd;+    MV_U8*                  pDigest;+    MV_CESA_MAC_MODE        macMode;+    MV_U8*                  pOuterIV = NULL;++    /* Copy data from Source fragment to Destination */+    if(pCmd->pSrc != pCmd->pDst)+    {+        mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,+                       pCmd->pSrc, pReq->frags.bufOffset, macDataSize);+    }++/*+    mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);+    mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);+*/+    pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);++    macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;+/*+    mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",+            macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);+*/+    switch(macMode)+    {+        case MV_CESA_MAC_HMAC_MD5:+            pOuterIV = pSA->pSramSA->macOuterIV;++        case MV_CESA_MAC_MD5:+            mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,+                               macDataSize, pCmd->macLength, pDigest);+        break;++        case MV_CESA_MAC_HMAC_SHA1:+            pOuterIV = pSA->pSramSA->macOuterIV;++        case MV_CESA_MAC_SHA1:+            mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,+                               macDataSize, pCmd->macLength, pDigest);+        break;++        default:+            mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);+            return MV_BAD_PARAM;+    }+    return MV_OK;+}++/*******************************************************************************+* mvCesaCtrModeInit -+*+* DESCRIPTION:+*+*+* INPUT: NONE+*+*+* RETURN:+*       MV_CESA_COMMAND*+*+*******************************************************************************/+static MV_CESA_COMMAND*    mvCesaCtrModeInit(void)+{+    MV_CESA_MBUF    *pMbuf;+    MV_U8           *pBuf;+    MV_CESA_COMMAND *pCmd;++    pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) ++                      sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);+    if(pBuf == NULL)+    {+        mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",+                    sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );+        return NULL;+    }+    pCmd = (MV_CESA_COMMAND*)pBuf;+    pBuf += sizeof(MV_CESA_COMMAND);++    pMbuf = (MV_CESA_MBUF*)pBuf;+    pBuf += sizeof(MV_CESA_MBUF);++    pMbuf->pFrags = (MV_BUF_INFO*)pBuf;++    pMbuf->numFrags = 1;+    pCmd->pSrc = pMbuf;+    pCmd->pDst = pMbuf;+/*+    mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",+                pCmd, pCmd->pSrc, pCmd->pDst,+                pMbuf->pFrags);+*/+    return pCmd;+}++/*******************************************************************************+* mvCesaCtrModePrepare -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static MV_STATUS    mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)+{+    MV_CESA_MBUF    *pMbuf;+    MV_U8           *pBuf, *pIV;+    MV_U32          counter, *pCounter;+    int             cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);+/*+    mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",+                pCmd, pCmd->pSrc, pCmd->pDst,+                pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);+*/+    pMbuf = pCtrModeCmd->pSrc;++    /* Allocate buffer for Key stream */+    pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize, +			      &pMbuf->pFrags[0].bufPhysAddr,+			      &pMbuf->pFrags[0].memHandle);+    if(pBuf == NULL)+    {+        mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);+        return MV_OUT_OF_CPU_MEM;+    }+    memset(pBuf, 0, cryptoSize);+    mvOsCacheFlush(NULL, pBuf, cryptoSize);++    pMbuf->pFrags[0].bufVirtPtr = pBuf;+    pMbuf->mbufSize = cryptoSize;+    pMbuf->pFrags[0].bufSize = cryptoSize;++    pCtrModeCmd->pReqPrv = pCmd->pReqPrv;+    pCtrModeCmd->sessionId = pCmd->sessionId;++    /* ivFromUser and ivOffset are don't care */+    pCtrModeCmd->cryptoOffset = 0;+    pCtrModeCmd->cryptoLength = cryptoSize;++    /* digestOffset, macOffset and macLength are don't care */++    mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);+    pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));+    counter = *pCounter;+    counter = MV_32BIT_BE(counter);+    pIV = pBuf;+    cryptoSize -= MV_CESA_AES_BLOCK_SIZE;++    /* fill key stream */+    while(cryptoSize > 0)+    {+        pBuf += MV_CESA_AES_BLOCK_SIZE;+        memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));+        pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));+        counter++;+        *pCounter = MV_32BIT_BE(counter);+        cryptoSize -= MV_CESA_AES_BLOCK_SIZE;+    }++    return MV_OK;+}++/*******************************************************************************+* mvCesaCtrModeComplete -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static MV_STATUS   mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)+{+    int         srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;+    int         cryptoSize = pCmd->cryptoLength;+    MV_U8       *pSrc, *pDst, *pKey;+    MV_STATUS   status = MV_OK;+/*+    mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",+                pCmd, pCmd->pSrc, pCmd->pDst,+                pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);+*/+    /* XOR source data with key stream to destination data */+    pKey = pCmd->pDst->pFrags[0].bufVirtPtr;+    keyOffset = 0;++    if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&+        (pOrgCmd->cryptoOffset > 0) )+    {+        /* Copy Prefix from source buffer to destination buffer */++        status = mvCesaMbufCopy(pOrgCmd->pDst, 0,+                                pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);+/*+        status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,+                       0, pOrgCmd->cryptoOffset);+        status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,+                       0, pOrgCmd->cryptoOffset);+*/+    }++    srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);+    pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;+    srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;++    dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);+    pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;+    dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;++    while(cryptoSize > 0)+    {+        pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);++        cryptoSize--;+        dstOffset++;+        srcOffset++;+        keyOffset++;++        if(srcOffset >= srcSize)+        {+            srcFrag++;+            srcOffset = 0;+            pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;+            srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;+        }++        if(dstOffset >= dstSize)+        {+            dstFrag++;+            dstOffset = 0;+            pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;+            dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;+        }+    }++    if(pOrgCmd->pSrc != pOrgCmd->pDst)+    {+        /* Copy Suffix from source buffer to destination buffer */+        srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;++        if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)+        {+            status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,+                                    pOrgCmd->pSrc, srcOffset,+                                    pOrgCmd->pDst->mbufSize - srcOffset);+        }++/*+        status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,+                                srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);+        status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,+                       srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);+*/+    }++    /* Free buffer used for Key stream */+    mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,+		     pCmd->pDst->pFrags[0].bufPhysAddr,+                     pCmd->pDst->pFrags[0].bufVirtPtr,+		     pCmd->pDst->pFrags[0].memHandle);++    return MV_OK;+}++/*******************************************************************************+* mvCesaCtrModeFinish -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_COMMAND* pCmd+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static void    mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)+{+    mvOsFree(pCmd);+}++/*******************************************************************************+* mvCesaParamCheck -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static MV_STATUS   mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,+                                    MV_U8* pFixOffset)+{+    MV_U8   fixOffset = 0xFF;++    /* Check AUTH operation parameters */+    if( ((pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )+    {+        /* MAC offset should be at least 4 byte aligned */+        if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )+        {+            mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",+                    pCmd->macOffset);+            return MV_BAD_PARAM;+        }+        /* Digest offset must be 4 byte aligned */+        if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )+        {+            mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",+                    pCmd->digestOffset);+            return MV_BAD_PARAM;+        }+        /* In addition all offsets should be the same alignment: 8 or 4 */+        if(fixOffset == 0xFF)+        {+            fixOffset = (pCmd->macOffset % 8);+        }+        else+        {+            if( (pCmd->macOffset % 8) != fixOffset)+            {+                mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",+                                pCmd->macOffset, fixOffset);+                return MV_BAD_PARAM;+            }+        }+        if( (pCmd->digestOffset % 8) != fixOffset)+        {+            mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",+                                pCmd->digestOffset, fixOffset);+            return MV_BAD_PARAM;+        }+    }+    /* Check CRYPTO operation parameters */+    if( ((pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )+    {+        /* CryptoOffset should be at least 4 byte aligned */+        if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4)  )+        {+            mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",+                        pCmd->cryptoOffset);+            return MV_BAD_PARAM;+        }+        /* cryptoLength should be the whole number of blocks */+        if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )+        {+            mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",+                        pCmd->cryptoLength, pSA->cryptoBlockSize);+            return MV_BAD_PARAM;+        }+        if(fixOffset == 0xFF)+        {+            fixOffset = (pCmd->cryptoOffset % 8);+        }+        else+        {+            /* In addition all offsets should be the same alignment: 8 or 4 */+            if( (pCmd->cryptoOffset % 8) != fixOffset)+            {+                mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",+                                pCmd->cryptoOffset, fixOffset);+                return MV_BAD_PARAM;+            }+        }++        /* check for CBC mode */+        if(pSA->cryptoIvSize > 0)+        {+            /* cryptoIV must not be part of CryptoLength */+            if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&+                (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )+            {+                mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",+                        pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);+                return MV_BAD_PARAM;+            }++            /* ivOffset must be 4 byte aligned */+            if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )+            {+                mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",+                            pCmd->ivOffset);+                return MV_BAD_PARAM;+            }+            /* In addition all offsets should be the same alignment: 8 or 4 */+            if( (pCmd->ivOffset % 8) != fixOffset)+            {+                mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",+                                pCmd->ivOffset, fixOffset);+                return MV_BAD_PARAM;+            }+        }+    }+    return MV_OK;+}++/*******************************************************************************+* mvCesaFragParamCheck -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static MV_STATUS   mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)+{+    int     offset;++    if( ((pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )+    {+        /* macOffset must be less that SRAM buffer size */+        if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))+        {+            mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",+                        pCmd->macOffset);+            return MV_BAD_PARAM;+        }+        /* macOffset+macSize must be more than mbufSize - SRAM buffer size */+        if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||+            ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=+             sizeof(cesaSramVirtPtr->buf)) )+        {+            mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",+                        pCmd->macLength, pCmd->pSrc->mbufSize);+            return MV_BAD_PARAM;+        }+    }++    if( ((pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )+    {+        /* cryptoOffset must be less that SRAM buffer size */+        /* 4 for possible fixOffset */+        if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))+        {+            mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",+                        pCmd->cryptoOffset);+            return MV_BAD_PARAM;+        }++        /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */+        if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||+            ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=+             (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )+        {+            mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",+                        pCmd->cryptoLength, pCmd->pSrc->mbufSize);+            return MV_BAD_PARAM;+        }+    }++    /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */+    if( ((pSA->config & MV_CESA_OPERATION_MASK) ==+            (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||+        ((pSA->config & MV_CESA_OPERATION_MASK) ==+            (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )+    {+        if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||+            ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&+              (mvCtrlRevGet() >= MV_5181L_A0_REV)  &&+              (pCmd->macLength >= (1 << 14)) ) )+        {+            return MV_NOT_ALLOWED;+        }++        /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */+        if(pCmd->cryptoOffset > pCmd->macOffset)+        {+            offset = pCmd->cryptoOffset - pCmd->macOffset;+        }+        else+        {+            offset = pCmd->macOffset - pCmd->cryptoOffset;+        }++        if( MV_IS_NOT_ALIGN(offset,  pSA->cryptoBlockSize) )+        {+/*+            mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",+                        pSA->cryptoBlockSize);+*/+            return MV_NOT_ALLOWED;+        }+        /* Digest must not be part of CryptoLength */+        if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&+            (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )+        {+/*+            mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",+                        pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);+*/+            return MV_NOT_ALLOWED;+        }+    }+    return MV_OK;+}++/*******************************************************************************+* mvCesaFragSizeFind -+*+* DESCRIPTION:+*+*+* INPUT:+*       MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,+*       int cryptoOffset, int macOffset,+*+* OUTPUT:+*       int* pCopySize, int* pCryptoDataSize, int* pMacDataSize+*+* RETURN:+*       MV_STATUS+*+*******************************************************************************/+static void   mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,+                                 int cryptoOffset, int macOffset,+                          int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)+{+    MV_CESA_COMMAND *pCmd = pReq->pCmd;+    int             cryptoDataSize, macDataSize, copySize;++    cryptoDataSize = macDataSize = 0;+    copySize = *pCopySize;++    if( (pSA->config & MV_CESA_OPERATION_MASK) !=+                (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )+    {+        cryptoDataSize = MV_MIN( (copySize - cryptoOffset),+                                 (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );++        /* cryptoSize for each fragment must be the whole number of blocksSize */+        if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )+        {+            cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);+            copySize = cryptoOffset + cryptoDataSize;+        }+    }+    if( (pSA->config & MV_CESA_OPERATION_MASK) !=+             (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )+    {+        macDataSize = MV_MIN( (copySize - macOffset),+                              (pCmd->macLength - (pReq->frags.macSize + 1)));++        /* macSize for each fragment (except last) must be the whole number of blocksSize */+        if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )+        {+            macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);+            copySize = macOffset + macDataSize;+        }+        cryptoDataSize = copySize - cryptoOffset;+    }+    *pCopySize = copySize;++    if(pCryptoDataSize != NULL)+        *pCryptoDataSize = cryptoDataSize;++    if(pMacDataSize != NULL)+        *pMacDataSize = macDataSize;+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaDebug.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaDebug.c	2010-11-09 20:28:05.342495385 +0100@@ -0,0 +1,484 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvOs.h"+#include "mvDebug.h"++#include "cesa/mvMD5.h"+#include "cesa/mvSHA1.h"++#include "cesa/mvCesa.h"+#include "cesa/mvCesaRegs.h"+#include "cesa/AES/mvAes.h"++static const char*   mvCesaDebugStateStr(MV_CESA_STATE state)+{+    switch(state)+    {+        case MV_CESA_IDLE:+            return "Idle";++        case MV_CESA_PENDING:+            return "Pend";++        case MV_CESA_PROCESS:+            return "Proc";++        case MV_CESA_READY:+            return "Ready";++        default:+            break;+    }+    return "Unknown";+}++static const char*   mvCesaDebugOperStr(MV_CESA_OPERATION oper)+{+    switch(oper)+    {+        case MV_CESA_MAC_ONLY:+            return "MacOnly";++        case MV_CESA_CRYPTO_ONLY:+            return "CryptoOnly";++        case MV_CESA_MAC_THEN_CRYPTO:+            return "MacCrypto";++        case MV_CESA_CRYPTO_THEN_MAC:+            return "CryptoMac";++        default:+            break;+    }+    return "Null";+}++static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)+{+    switch(cryptoAlg)+    {+        case MV_CESA_CRYPTO_DES:+            return "DES";++        case MV_CESA_CRYPTO_3DES:+            return "3DES";++        case MV_CESA_CRYPTO_AES:+            return "AES";++        default:+            break;+    }+    return "Null";+}++static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)+{+    switch(macMode)+    {+        case MV_CESA_MAC_MD5:+            return "MD5";++        case MV_CESA_MAC_SHA1:+            return "SHA1";++        case MV_CESA_MAC_HMAC_MD5:+            return "HMAC-MD5";++        case MV_CESA_MAC_HMAC_SHA1:+            return "HMAC_SHA1";++        default:+            break;+    }+    return "Null";+}++void    mvCesaDebugCmd(MV_CESA_COMMAND* pCmd,  int mode)+{+    mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",+                pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,+                pCmd->pFuncCB, pCmd->sessionId);+    mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",+                pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,+                pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);+}++/* no need to use in tool */+void     mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)+{+    int frag, len, fragOffset;++    if(str != NULL)+        mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",+                    str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);++    frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);+    if(frag == MV_INVALID)+    {+        mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);+        return;+    }++    for(; frag<pMbuf->numFrags; frag++)+    {+        mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",+                    frag, pMbuf->pFrags[frag].bufVirtPtr,+                    pMbuf->pFrags[frag].bufSize);+        if(size > 0)+        {+            len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);+            mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);+            size -= len;+            fragOffset = 0;+        }+    }+}++void    mvCesaDebugRegs(void)+{+    mvOsPrintf("\t CESA Registers:\n");++    mvOsPrintf("MV_CESA_CMD_REG                     : 0x%X = 0x%08x\n",+                MV_CESA_CMD_REG,+                MV_REG_READ( MV_CESA_CMD_REG ) );++    mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG        : 0x%X = 0x%08x\n",+                MV_CESA_CHAN_DESC_OFFSET_REG,+                MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );++    mvOsPrintf("MV_CESA_CFG_REG                     : 0x%X = 0x%08x\n",+                MV_CESA_CFG_REG,+                MV_REG_READ( MV_CESA_CFG_REG ) );++    mvOsPrintf("MV_CESA_STATUS_REG                  : 0x%X = 0x%08x\n",+                MV_CESA_STATUS_REG,+                MV_REG_READ( MV_CESA_STATUS_REG ) );++    mvOsPrintf("MV_CESA_ISR_CAUSE_REG               : 0x%X = 0x%08x\n",+                MV_CESA_ISR_CAUSE_REG,+                MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );++    mvOsPrintf("MV_CESA_ISR_MASK_REG                : 0x%X = 0x%08x\n",+                MV_CESA_ISR_MASK_REG,+                MV_REG_READ( MV_CESA_ISR_MASK_REG ) );+#if (MV_CESA_VERSION >= 2)+    mvOsPrintf("MV_CESA_TDMA_CTRL_REG               : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_CTRL_REG, +                MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );++    mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG         : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_BYTE_COUNT_REG, +                MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );++    mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG           : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_SRC_ADDR_REG, +                MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );++    mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG           : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_DST_ADDR_REG, +                MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );++    mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG      : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_NEXT_DESC_PTR_REG, +                MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );++    mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG      : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_CURR_DESC_PTR_REG, +                MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );++    mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG        : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_ERROR_CAUSE_REG, +                MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );++    mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG         : 0x%X = 0x%08x\n", +                MV_CESA_TDMA_ERROR_MASK_REG, +                MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );++#endif+}++void    mvCesaDebugStatus(void)+{+    mvOsPrintf("\n\t CESA Status\n\n");++    mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",+                pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),+                cesaReqResources);+#if (MV_CESA_VERSION >= 3)+    mvOsPrintf("chainLength=%u\n",cesaChainLength);+#else+   mvOsPrintf("\n"); 	+#endif++    mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",+                pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));++    mvOsPrintf("\n");++    mvCesaDebugRegs();+    mvCesaDebugStats();+    mvCesaDebugStatsClear();+}++void    mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)+{+    mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",+            pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);++    mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",+            pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,+            pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);++    mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",+            pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,+            pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);+}++void    mvCesaDebugQueue(int mode)+{+    mvOsPrintf("\n\t CESA Request Queue:\n\n");++    mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",+                pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));++    mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",+                pCesaReqEmpty, pCesaReqProcess,+                cesaReqResources);++    if(mode != 0)+    {+        int             count = 0;+        MV_CESA_REQ*    pReq = pCesaReqFirst;++        for(count=0; count<cesaQueueDepth; count++)+        {+            /* Print out requsts */+            mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",+                count, pReq, mvCesaDebugStateStr(pReq->state),+                pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);+            if(pReq->fragMode != MV_CESA_FRAG_NONE)+            {+                int frag;++                mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",+                            &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,+                            pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);+                for(frag=0; frag<pReq->frags.numFrag; frag++)+                {+                    mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,+                                pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);+                }+            }+            if(mode > 1)+            {+                /* Print out Command */+                mvCesaDebugCmd(pReq->pCmd, mode);++                /* Print out Descriptor */+                mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);+            }+            pReq++;+        }+    }+}+++void    mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)+{+    if(pSramSA == NULL)+    {+        mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);+        return;+    }+    mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",+                pSramSA, sizeof(MV_CESA_SRAM_SA));++    if(mode != 0)+    {+        mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",+                    pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);+        mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);++        mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",+                    pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);+        mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);++        mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",+                    pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);+        mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);+    }+}++void    mvCesaDebugSA(short sid, int mode)+{+    MV_CESA_OPERATION   oper;+    MV_CESA_DIRECTION   dir;+    MV_CESA_CRYPTO_ALG  cryptoAlg;+    MV_CESA_CRYPTO_MODE cryptoMode;+    MV_CESA_MAC_MODE    macMode;+    MV_CESA_SA*         pSA = &pCesaSAD[sid];++    if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )+    {+        mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",+                    sid, pSA,+                    pSA->valid ? "Valid" : "Invalid", pSA->count);++        oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;+        dir  = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;+        mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),+                    (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");+        if(oper != MV_CESA_MAC_ONLY)+        {+            cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;+            cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;+            mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),+                        (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");+        }+        if(oper != MV_CESA_CRYPTO_ONLY)+        {+            macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;+            mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));+        }+        mvOsPrintf("\n");++        if(mode > 0)+        {+            mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",+                        pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,+                        pCesaSAD[sid].digestSize);++            mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);+        }+    }+}+++/**/+void    mvCesaDebugSram(int mode)+{+    mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",+            sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);++    mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",+                    MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);+        if(mode != 0)+            mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);++    mvOsPrintf("\n");+    mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",+                    sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);+    if(mode != 0)+    {+        mvOsPrintf("\n");+        mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);+    }+    mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",+                    MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);+    if(mode != 0)+    {+        mvOsPrintf("\n");+        mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);+    }+    mvOsPrintf("\n");+    mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);+}++void    mvCesaDebugSAD(int mode)+{+    int sid;++    mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",+                pCesaSAD, cesaMaxSA);++    for(sid=0; sid<cesaMaxSA; sid++)+    {+        mvCesaDebugSA(sid, mode);+    }+}++void    mvCesaDebugStats(void)+{+    mvOsPrintf("\n\t Cesa Statistics\n");++    mvOsPrintf("Opened=%u, Closed=%u\n",+                cesaStats.openedCount, cesaStats.closedCount);+    mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",+                cesaStats.reqCount, cesaStats.maxReqCount,+                cesaStats.fragCount, cesaStats.startCount);+#if (MV_CESA_VERSION >= 3)+    mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);+#endif+    mvOsPrintf("\n");+    mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",+                cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);+}++void    mvCesaDebugStatsClear(void)+{+    memset(&cesaStats, 0, sizeof(cesaStats));+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesa.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesa.h	2010-11-09 20:28:05.737859537 +0100@@ -0,0 +1,412 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/*******************************************************************************+* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator+*+* DESCRIPTION:+*       This header file contains macros typedefs and function declaration for+*       the Marvell Cryptographic Engines and Security Accelerator.+*+*******************************************************************************/++#ifndef __mvCesa_h__+#define __mvCesa_h__++#include "mvOs.h"+#include "mvCommon.h"+#include "mvDebug.h"++#include "ctrlEnv/mvCtrlEnvSpec.h"++#include "cesa/mvMD5.h"+#include "cesa/mvSHA1.h"++#include "cesa/mvCesa.h"+#include "cesa/AES/mvAes.h"+#include "mvSysHwConfig.h"++#ifdef MV_INCLUDE_IDMA+#include "idma/mvIdma.h"+#include "idma/mvIdmaRegs.h"+#else+/* Redefine MV_DMA_DESC structure */+typedef struct _mvDmaDesc+{+    MV_U32 	byteCnt;        /* The total number of bytes to transfer        */+    MV_U32 	phySrcAdd;	    /* The physical source address                  */+    MV_U32 	phyDestAdd;     /* The physical destination address             */+    MV_U32	phyNextDescPtr; /* If we are using chain mode DMA transfer,     */+				            /* then this pointer should point to the        */+                            /* physical address of the next descriptor,     */+                            /* otherwise it should be NULL.                 */+}MV_DMA_DESC;+#endif /* MV_INCLUDE_IDMA */++#include "cesa/mvCesaRegs.h"++#define MV_CESA_AUTH_BLOCK_SIZE         64 /* bytes */++#define MV_CESA_MD5_DIGEST_SIZE         16 /* bytes */+#define MV_CESA_SHA1_DIGEST_SIZE        20 /* bytes */++#define MV_CESA_MAX_DIGEST_SIZE         MV_CESA_SHA1_DIGEST_SIZE++#define MV_CESA_DES_KEY_LENGTH          8   /* bytes = 64 bits */+#define MV_CESA_3DES_KEY_LENGTH         24  /* bytes = 192 bits */+#define MV_CESA_AES_128_KEY_LENGTH      16  /* bytes = 128 bits */+#define MV_CESA_AES_192_KEY_LENGTH      24  /* bytes = 192 bits */+#define MV_CESA_AES_256_KEY_LENGTH      32  /* bytes = 256 bits */++#define MV_CESA_MAX_CRYPTO_KEY_LENGTH   MV_CESA_AES_256_KEY_LENGTH++#define MV_CESA_DES_BLOCK_SIZE          8 /* bytes = 64 bits */+#define MV_CESA_3DES_BLOCK_SIZE         8 /* bytes = 64 bits */++#define MV_CESA_AES_BLOCK_SIZE          16 /* bytes = 128 bits */++#define MV_CESA_MAX_IV_LENGTH           MV_CESA_AES_BLOCK_SIZE++#define MV_CESA_MAX_MAC_KEY_LENGTH      64 /* bytes */++typedef struct+{+	MV_U8               cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];+	MV_U8               macKey[MV_CESA_MAX_MAC_KEY_LENGTH];+	MV_CESA_OPERATION   operation;+	MV_CESA_DIRECTION   direction;+	MV_CESA_CRYPTO_ALG  cryptoAlgorithm;+	MV_CESA_CRYPTO_MODE cryptoMode;+   	MV_U8               cryptoKeyLength;+	MV_CESA_MAC_MODE    macMode;+	MV_U8               macKeyLength;+	MV_U8               digestSize;++} MV_CESA_OPEN_SESSION;++typedef struct+{+    MV_BUF_INFO *pFrags;+	MV_U16	    numFrags;+    MV_U16      mbufSize;++} MV_CESA_MBUF;++typedef struct+{+    void* 	pReqPrv; /* instead of reqId */+    MV_U32 	retCode;+    MV_16   sessionId;++} MV_CESA_RESULT;++typedef void    (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);+++typedef struct+{+    void*               pReqPrv;    /* instead of reqId */+    MV_CESA_MBUF*       pSrc;+    MV_CESA_MBUF*       pDst;+    MV_CESA_CALLBACK*   pFuncCB;+    MV_16               sessionId;+    MV_U16              ivFromUser;+    MV_U16              ivOffset;+    MV_U16              cryptoOffset;+    MV_U16              cryptoLength;+    MV_U16              digestOffset;+    MV_U16              macOffset;+    MV_U16              macLength;+    MV_BOOL		skipFlush;+} MV_CESA_COMMAND;++++MV_STATUS   mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);+MV_STATUS   mvCesaFinish (void);+MV_STATUS   mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);+MV_STATUS   mvCesaSessionClose(short sid);+MV_STATUS   mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);++MV_STATUS   mvCesaAction (MV_CESA_COMMAND* pCmd);++MV_U32      mvCesaInProcessGet(void);+MV_STATUS   mvCesaReadyDispatch(void);+MV_STATUS   mvCesaReadyGet(MV_CESA_RESULT* pResult);+MV_BOOL     mvCesaIsReady(void);++int     	mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);+MV_STATUS   mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,+                               int offset, int size);+MV_STATUS   mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,+                               int offset, int size);+MV_STATUS   mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,+                           MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);++/********** Debug functions ********/++void        mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);+void        mvCesaDebugSA(short sid, int mode);+void        mvCesaDebugStats(void);+void        mvCesaDebugStatsClear(void);+void        mvCesaDebugRegs(void);+void        mvCesaDebugStatus(void);+void        mvCesaDebugQueue(int mode);+void        mvCesaDebugSram(int mode);+void        mvCesaDebugSAD(int mode);+++/********  CESA Private definitions ********/+#if (MV_CESA_VERSION >= 2)+#if (MV_CACHE_COHERENCY  == MV_CACHE_COHER_SW)+#define MV_CESA_TDMA_CTRL_VALUE       MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \+                                    | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \+                                    | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK                   \+				    | MV_CESA_TDMA_NO_BYTE_SWAP_MASK			   \+                                    | MV_CESA_TDMA_ENABLE_MASK+#else+#define MV_CESA_TDMA_CTRL_VALUE       MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B)  \+                                    | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \+                                    /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK                   */\+                                    | MV_CESA_TDMA_ENABLE_MASK++#endif+#else+#define MV_CESA_IDMA_CTRL_LOW_VALUE   ICCLR_DST_BURST_LIM_128BYTE   \+                                    | ICCLR_SRC_BURST_LIM_128BYTE   \+                                    | ICCLR_INT_MODE_MASK           \+                                    | ICCLR_BLOCK_MODE              \+                                    | ICCLR_CHAN_ENABLE             \+                                    | ICCLR_DESC_MODE_16M+#endif /* MV_CESA_VERSION >= 2 */++#define MV_CESA_MAX_PKT_SIZE        (64 * 1024)+#define MV_CESA_MAX_MBUF_FRAGS      20++#define MV_CESA_MAX_REQ_FRAGS       ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)++#define MV_CESA_MAX_DMA_DESC    (MV_CESA_MAX_MBUF_FRAGS*2 + 5)++#define MAX_CESA_CHAIN_LENGTH	20++typedef enum+{+    MV_CESA_IDLE     = 0,+    MV_CESA_PENDING,+    MV_CESA_PROCESS,+    MV_CESA_READY,+#if (MV_CESA_VERSION >= 3)+    MV_CESA_CHAIN,+#endif+} MV_CESA_STATE;+++/* Session database */++/* Map of Key materials of the session in SRAM.+ * Each field must be 8 byte aligned+ * Total size: 32 + 24 + 24 = 80 bytes+ */+typedef struct+{+    MV_U8  cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];+    MV_U8  macInnerIV[MV_CESA_MAX_DIGEST_SIZE];+    MV_U8  reservedInner[4];+    MV_U8  macOuterIV[MV_CESA_MAX_DIGEST_SIZE];+    MV_U8  reservedOuter[4];++} MV_CESA_SRAM_SA;++typedef struct+{+    MV_CESA_SRAM_SA*    pSramSA;+    MV_U32              config;+    MV_U8               cryptoKeyLength;+    MV_U8               cryptoIvSize;+    MV_U8               cryptoBlockSize;+    MV_U8               digestSize;+    MV_U8               macKeyLength;+    MV_U8               valid;+    MV_U8               ctrMode;+    MV_U32              count;++} MV_CESA_SA;++/* DMA list management */+typedef struct+{+    MV_DMA_DESC*    pDmaFirst;+    MV_DMA_DESC*    pDmaLast;++} MV_CESA_DMA;+++typedef struct+{+    MV_U8               numFrag;+    MV_U8               nextFrag;+    int                 bufOffset;+    int                 cryptoSize;+    int                 macSize;+    int                 newDigestOffset;+    MV_U8               orgDigest[MV_CESA_MAX_DIGEST_SIZE];++} MV_CESA_FRAGS;++/* Request queue */+typedef struct+{+    MV_U8               state;+    MV_U8               fragMode;+    MV_U8               fixOffset;+    MV_CESA_COMMAND*    pCmd;+    MV_CESA_COMMAND*    pOrgCmd;+    MV_BUF_INFO         dmaDescBuf;+    MV_CESA_DMA         dma[MV_CESA_MAX_REQ_FRAGS];+    MV_BUF_INFO         cesaDescBuf;+    MV_CESA_DESC*       pCesaDesc;+    MV_CESA_FRAGS       frags;+++} MV_CESA_REQ;+++/* SRAM map */+/* Total SRAM size calculation */+/*  SRAM size =+ *              MV_CESA_MAX_BUF_SIZE  ++ *              sizeof(MV_CESA_DESC)  ++ *              MV_CESA_MAX_IV_LENGTH ++ *              MV_CESA_MAX_IV_LENGTH ++ *              MV_CESA_MAX_DIGEST_SIZE ++ *              sizeof(MV_CESA_SRAM_SA)+ *            = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes+ *            = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes+ */+typedef struct+{+    MV_U8               buf[MV_CESA_MAX_BUF_SIZE];+    MV_CESA_DESC        desc;+    MV_U8               cryptoIV[MV_CESA_MAX_IV_LENGTH];+    MV_U8               tempCryptoIV[MV_CESA_MAX_IV_LENGTH];+    MV_U8               tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];+    MV_CESA_SRAM_SA     sramSA;++} MV_CESA_SRAM_MAP;+++typedef struct+{+    MV_U32  openedCount;+    MV_U32  closedCount;+    MV_U32  fragCount;+    MV_U32  reqCount;+    MV_U32  maxReqCount;+    MV_U32  procCount;+    MV_U32  readyCount;+    MV_U32  notReadyCount;+    MV_U32  startCount;+#if (MV_CESA_VERSION >= 3)+    MV_U32  maxChainUsage;+#endif++} MV_CESA_STATS;+++/* External variables */++extern MV_CESA_STATS    cesaStats;+extern MV_CESA_FRAGS    cesaFrags;++extern MV_BUF_INFO      cesaSramSaBuf;++extern MV_CESA_SA*       pCesaSAD;+extern MV_U16            cesaMaxSA;++extern MV_CESA_REQ*      pCesaReqFirst;+extern MV_CESA_REQ*      pCesaReqLast;+extern MV_CESA_REQ*      pCesaReqEmpty;+extern MV_CESA_REQ*      pCesaReqProcess;+extern int               cesaQueueDepth;+extern int               cesaReqResources;+#if (MV_CESA_VERSION>= 3)+extern MV_U32		cesaChainLength;+#endif++extern MV_CESA_SRAM_MAP*  cesaSramVirtPtr;+extern MV_U32           cesaSramPhysAddr;++static INLINE MV_ULONG  mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)+{+    return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));+}++/* Additional DEBUG functions */+void        mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);+void        mvCesaDebugCmd(MV_CESA_COMMAND* pCmd,  int mode);+void        mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);++++#endif /* __mvCesa_h__ */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaRegs.h	2010-11-09 20:28:05.772495441 +0100@@ -0,0 +1,357 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __mvCesaRegs_h__+#define __mvCesaRegs_h__++#include "mvTypes.h"++typedef struct+{+    /* word 0 */+    MV_U32  config;+    /* word 1 */    +    MV_U16  cryptoSrcOffset;+    MV_U16  cryptoDstOffset;+    /* word 2 */    +    MV_U16  cryptoDataLen;+    MV_U16  reserved1;+    /* word 3 */+    MV_U16  cryptoKeyOffset;+    MV_U16  reserved2;+    /* word 4 */+    MV_U16  cryptoIvOffset;+    MV_U16  cryptoIvBufOffset;+    /* word 5 */+    MV_U16  macSrcOffset;+    MV_U16  macTotalLen;+    /* word 6 */+    MV_U16  macDigestOffset;+    MV_U16  macDataLen;+    /* word 7 */+    MV_U16  macInnerIvOffset;+    MV_U16  macOuterIvOffset;++} MV_CESA_DESC;++/* operation */+typedef enum +{+    MV_CESA_MAC_ONLY         = 0,+    MV_CESA_CRYPTO_ONLY      = 1,+    MV_CESA_MAC_THEN_CRYPTO  = 2,+    MV_CESA_CRYPTO_THEN_MAC  = 3,+    +    MV_CESA_MAX_OPERATION++} MV_CESA_OPERATION;++#define MV_CESA_OPERATION_OFFSET        0+#define MV_CESA_OPERATION_MASK          (0x3 << MV_CESA_OPERATION_OFFSET)++/* mac algorithm */+typedef enum +{   +    MV_CESA_MAC_NULL        = 0,+    MV_CESA_MAC_MD5         = 4,+    MV_CESA_MAC_SHA1        = 5,+    MV_CESA_MAC_HMAC_MD5    = 6,+    MV_CESA_MAC_HMAC_SHA1   = 7,++} MV_CESA_MAC_MODE;++#define MV_CESA_MAC_MODE_OFFSET         4+#define MV_CESA_MAC_MODE_MASK           (0x7 << MV_CESA_MAC_MODE_OFFSET)++typedef enum+{+    MV_CESA_MAC_DIGEST_FULL = 0,+    MV_CESA_MAC_DIGEST_96B  = 1,++} MV_CESA_MAC_DIGEST_SIZE;++#define MV_CESA_MAC_DIGEST_SIZE_BIT     7+#define MV_CESA_MAC_DIGEST_SIZE_MASK    (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)+++typedef enum +{+    MV_CESA_CRYPTO_NULL = 0,+    MV_CESA_CRYPTO_DES  = 1,+    MV_CESA_CRYPTO_3DES = 2,+    MV_CESA_CRYPTO_AES  = 3,++} MV_CESA_CRYPTO_ALG;++#define MV_CESA_CRYPTO_ALG_OFFSET       8+#define MV_CESA_CRYPTO_ALG_MASK         (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)+++/* direction */+typedef enum +{+    MV_CESA_DIR_ENCODE = 0,+    MV_CESA_DIR_DECODE = 1,++} MV_CESA_DIRECTION;++#define MV_CESA_DIRECTION_BIT           12+#define MV_CESA_DIRECTION_MASK          (1 << MV_CESA_DIRECTION_BIT)++/* crypto IV mode */+typedef enum +{+    MV_CESA_CRYPTO_ECB = 0,+    MV_CESA_CRYPTO_CBC = 1,++    /* NO HW Support */+    MV_CESA_CRYPTO_CTR = 10,++} MV_CESA_CRYPTO_MODE;++#define MV_CESA_CRYPTO_MODE_BIT         16+#define MV_CESA_CRYPTO_MODE_MASK        (1 << MV_CESA_CRYPTO_MODE_BIT)         ++/* 3DES mode */+typedef enum +{+    MV_CESA_CRYPTO_3DES_EEE = 0,+    MV_CESA_CRYPTO_3DES_EDE = 1,++} MV_CESA_CRYPTO_3DES_MODE;++#define MV_CESA_CRYPTO_3DES_MODE_BIT    20+#define MV_CESA_CRYPTO_3DES_MODE_MASK   (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)+++/* AES Key Length */+typedef enum +{+    MV_CESA_CRYPTO_AES_KEY_128 = 0,+    MV_CESA_CRYPTO_AES_KEY_192 = 1,+    MV_CESA_CRYPTO_AES_KEY_256 = 2,++} MV_CESA_CRYPTO_AES_KEY_LEN;++#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET   24+#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK     (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)++/* Fragmentation mode */+typedef enum +{+    MV_CESA_FRAG_NONE   = 0,+    MV_CESA_FRAG_FIRST  = 1,+    MV_CESA_FRAG_LAST   = 2,+    MV_CESA_FRAG_MIDDLE = 3,++} MV_CESA_FRAG_MODE;++#define MV_CESA_FRAG_MODE_OFFSET            30+#define MV_CESA_FRAG_MODE_MASK              (0x3 << MV_CESA_FRAG_MODE_OFFSET)+/*---------------------------------------------------------------------------*/++/********** Security Accelerator Command Register **************/+#define MV_CESA_CMD_REG                     (MV_CESA_REG_BASE + 0xE00)++#define MV_CESA_CMD_CHAN_ENABLE_BIT         0  +#define MV_CESA_CMD_CHAN_ENABLE_MASK        (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)++#define MV_CESA_CMD_CHAN_DISABLE_BIT        2  +#define MV_CESA_CMD_CHAN_DISABLE_MASK       (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)  ++/********** Security Accelerator Descriptor Pointers Register **********/+#define MV_CESA_CHAN_DESC_OFFSET_REG        (MV_CESA_REG_BASE + 0xE04)++/********** Security Accelerator Configuration Register **********/+#define MV_CESA_CFG_REG                     (MV_CESA_REG_BASE + 0xE08)++#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT     0+#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK    (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)++#define MV_CESA_CFG_WAIT_DMA_BIT            7+#define MV_CESA_CFG_WAIT_DMA_MASK           (1 << MV_CESA_CFG_WAIT_DMA_BIT)+          +#define MV_CESA_CFG_ACT_DMA_BIT             9+#define MV_CESA_CFG_ACT_DMA_MASK            (1 << MV_CESA_CFG_ACT_DMA_BIT)++#define MV_CESA_CFG_CHAIN_MODE_BIT          11+#define MV_CESA_CFG_CHAIN_MODE_MASK         (1 << MV_CESA_CFG_CHAIN_MODE_BIT)++/********** Security Accelerator Status Register ***********/+#define MV_CESA_STATUS_REG                  (MV_CESA_REG_BASE + 0xE0C)++#define MV_CESA_STATUS_ACTIVE_BIT           0+#define MV_CESA_STATUS_ACTIVE_MASK          (1 << MV_CESA_STATUS_ACTIVE_BIT)++#define MV_CESA_STATUS_DIGEST_ERR_BIT       8+#define MV_CESA_STATUS_DIGEST_ERR_MASK      (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)+++/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */+#define MV_CESA_ISR_CAUSE_REG               (MV_CESA_REG_BASE + 0xE20)++/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */+#define MV_CESA_ISR_MASK_REG                (MV_CESA_REG_BASE + 0xE24)++#define MV_CESA_CAUSE_AUTH_MASK             (1 << 0)+#define MV_CESA_CAUSE_DES_MASK              (1 << 1)+#define MV_CESA_CAUSE_AES_ENCR_MASK         (1 << 2)+#define MV_CESA_CAUSE_AES_DECR_MASK         (1 << 3)+#define MV_CESA_CAUSE_DES_ALL_MASK          (1 << 4)++#define MV_CESA_CAUSE_ACC_BIT               5+#define MV_CESA_CAUSE_ACC_MASK              (1 << MV_CESA_CAUSE_ACC_BIT)++#define MV_CESA_CAUSE_ACC_DMA_BIT           7+#define MV_CESA_CAUSE_ACC_DMA_MASK          (1 << MV_CESA_CAUSE_ACC_DMA_BIT)+#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK      (3 << MV_CESA_CAUSE_ACC_DMA_BIT)++#define MV_CESA_CAUSE_DMA_COMPL_BIT         9+#define MV_CESA_CAUSE_DMA_COMPL_MASK        (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)++#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT       10+#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK      (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)++#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT     11+#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK    (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)+++#define MV_CESA_AUTH_DATA_IN_REG            (MV_CESA_REG_BASE + 0xd38)+#define MV_CESA_AUTH_BIT_COUNT_LOW_REG      (MV_CESA_REG_BASE + 0xd20)+#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG     (MV_CESA_REG_BASE + 0xd24)++#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))++#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG  (MV_CESA_REG_BASE + 0xd00)+#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG  (MV_CESA_REG_BASE + 0xd04)+#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG  (MV_CESA_REG_BASE + 0xd08)+#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG  (MV_CESA_REG_BASE + 0xd0c)+#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG  (MV_CESA_REG_BASE + 0xd10)+#define MV_CESA_AUTH_COMMAND_REG            (MV_CESA_REG_BASE + 0xd18)++#define MV_CESA_AUTH_ALGORITHM_BIT          0+#define MV_CESA_AUTH_ALGORITHM_MD5          (0<<AUTH_ALGORITHM_BIT)+#define MV_CESA_AUTH_ALGORITHM_SHA1         (1<<AUTH_ALGORITHM_BIT)++#define MV_CESA_AUTH_IV_MODE_BIT            1+#define MV_CESA_AUTH_IV_MODE_INIT           (0<<AUTH_IV_MODE_BIT)+#define MV_CESA_AUTH_IV_MODE_CONTINUE       (1<<AUTH_IV_MODE_BIT)++#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT     2+#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK    (1<<AUTH_DATA_BYTE_SWAP_BIT)+++#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT       4+#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK      (1<<AUTH_IV_BYTE_SWAP_BIT)++#define MV_CESA_AUTH_TERMINATION_BIT        31+#define MV_CESA_AUTH_TERMINATION_MASK       (1<<AUTH_TERMINATION_BIT)+++/*************** TDMA Control Register ************************************************/+#define MV_CESA_TDMA_CTRL_REG               (MV_CESA_TDMA_REG_BASE + 0x840)++#define MV_CESA_TDMA_BURST_32B              3   +#define MV_CESA_TDMA_BURST_128B             4   ++#define MV_CESA_TDMA_DST_BURST_OFFSET       0+#define MV_CESA_TDMA_DST_BURST_ALL_MASK     (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)+#define MV_CESA_TDMA_DST_BURST_MASK(burst)  ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)++#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT   4+#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK  (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)++#define MV_CESA_TDMA_SRC_BURST_OFFSET       6+#define MV_CESA_TDMA_SRC_BURST_ALL_MASK     (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)+#define MV_CESA_TDMA_SRC_BURST_MASK(burst)  ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)++#define MV_CESA_TDMA_CHAIN_MODE_BIT         9+#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK    (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)++#define MV_CESA_TDMA_BYTE_SWAP_BIT	    11+#define MV_CESA_TDMA_BYTE_SWAP_MASK	    (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)+#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK	    (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)		    	++#define MV_CESA_TDMA_ENABLE_BIT		    12+#define MV_CESA_TDMA_ENABLE_MASK            (1<<MV_CESA_TDMA_ENABLE_BIT)+			    +#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT    13	+#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK   (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)	++#define MV_CESA_TDMA_CHAN_ACTIVE_BIT	    14    +#define MV_CESA_TDMA_CHAN_ACTIVE_MASK       (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)+/*------------------------------------------------------------------------------------*/++#define MV_CESA_TDMA_BYTE_COUNT_REG         (MV_CESA_TDMA_REG_BASE + 0x800)+#define MV_CESA_TDMA_SRC_ADDR_REG           (MV_CESA_TDMA_REG_BASE + 0x810)+#define MV_CESA_TDMA_DST_ADDR_REG           (MV_CESA_TDMA_REG_BASE + 0x820)+#define MV_CESA_TDMA_NEXT_DESC_PTR_REG      (MV_CESA_TDMA_REG_BASE + 0x830)+#define MV_CESA_TDMA_CURR_DESC_PTR_REG      (MV_CESA_TDMA_REG_BASE + 0x870)++#define MV_CESA_TDMA_ERROR_CAUSE_REG        (MV_CESA_TDMA_REG_BASE + 0x8C0)+#define MV_CESA_TDMA_ERROR_MASK_REG         (MV_CESA_TDMA_REG_BASE + 0x8C4)+++#endif /* __mvCesaRegs_h__ */ +diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaTest.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvCesaTest.c	2010-11-09 20:28:05.782495527 +0100@@ -0,0 +1,3096 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvOs.h"++#if defined(MV_VXWORKS)++#include "sysLib.h"+#include "logLib.h"+#include "tickLib.h"+#include "intLib.h"+#include "config.h"+++SEM_ID      cesaSemId = NULL;+SEM_ID      cesaWaitSemId = NULL;++#define CESA_TEST_LOCK(flags)       flags = intLock()+#define CESA_TEST_UNLOCK(flags)     intUnlock(flags)++#define CESA_TEST_WAIT_INIT()       cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)+#define CESA_TEST_WAKE_UP()         semGive(cesaWaitSemId)+#define CESA_TEST_WAIT(cond, ms)    semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)++#define CESA_TEST_TICK_GET()        tickGet()+#define CESA_TEST_TICK_TO_MS(tick)  (((tick)*1000)/sysClkRateGet())++#elif defined(MV_LINUX)++#include <linux/wait.h>+wait_queue_head_t   cesaTest_waitq;+spinlock_t          cesaLock;++#define CESA_TEST_LOCK(flags)       spin_lock_irqsave( &cesaLock, flags)+#define CESA_TEST_UNLOCK(flags)     spin_unlock_irqrestore( &cesaLock, flags);++#define CESA_TEST_WAIT_INIT()       init_waitqueue_head(&cesaTest_waitq)+#define CESA_TEST_WAKE_UP()         wake_up(&cesaTest_waitq)+#define CESA_TEST_WAIT(cond, ms)    wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))++#define CESA_TEST_TICK_GET()        jiffies+#define CESA_TEST_TICK_TO_MS(tick)  jiffies_to_msecs(tick)++#elif defined(MV_NETBSD)++#include <sys/param.h>+#include <sys/kernel.h>+static int	cesaLock;++#define	CESA_TEST_LOCK(flags)		flags = splnet()+#define	CESA_TEST_UNLOCK(flags)		splx(flags)++#define	CESA_TEST_WAIT_INIT()		/* nothing */+#define	CESA_TEST_WAKE_UP()		wakeup(&cesaLock)+#define	CESA_TEST_WAIT(cond, ms)	\+do {					\+	while (!(cond))			\+		tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \+} while (/*CONSTCOND*/0)++#define	CESA_TEST_TICK_GET()		hardclock_ticks+#define	CESA_TEST_TICK_TO_MS(tick)	((1000/hz)*(tick))++#define	request_irq(i,h,t,n,a)	\+	!mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))++#else+#error "Only Linux, VxWorks, or NetBSD OS are supported"+#endif++#include "mvDebug.h"++#include "mvSysHwConfig.h"+#include "boardEnv/mvBoardEnvLib.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "cntmr/mvCntmr.h"+#include "cesa/mvCesa.h"+#include "cesa/mvCesaRegs.h"+#include "cesa/mvMD5.h"+#include "cesa/mvSHA1.h"++#if defined(CONFIG_MV646xx)+#include "marvell_pic.h"+#endif++#define MV_CESA_USE_TIMER_ID    0+#define CESA_DEF_BUF_SIZE       1500+#define CESA_DEF_BUF_NUM        1+#define CESA_DEF_SESSION_NUM    32++#define CESA_DEF_ITER_NUM       100++#define CESA_DEF_REQ_SIZE       256+++/* CESA Tests Debug */+#undef CESA_TEST_DEBUG++#ifdef CESA_TEST_DEBUG++#   define CESA_TEST_DEBUG_PRINT(msg)   mvOsPrintf msg+#   define CESA_TEST_DEBUG_CODE(code)   code++typedef struct+{+    int             type;       /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */+    MV_U32          timeStamp;+    MV_U32          cause;+    MV_U32          realCause;+    MV_U32          dmaCause;+    int             resources;+    MV_CESA_REQ*    pReqReady;+    MV_CESA_REQ*    pReqEmpty;+    MV_CESA_REQ*    pReqProcess;+} MV_CESA_TEST_TRACE;++#define MV_CESA_TEST_TRACE_SIZE      25++static int cesaTestTraceIdx = 0;+static MV_CESA_TEST_TRACE    cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];++static void cesaTestTraceAdd(int type, MV_U32 cause)+{+    cesaTestTrace[cesaTestTraceIdx].type = type;+    cesaTestTrace[cesaTestTraceIdx].cause = cause;+    cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);+    cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);+    cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;+    cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;+    cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;+    cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;+    cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);+    cesaTestTraceIdx++;+    if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)+        cesaTestTraceIdx = 0;+}++#else++#   define CESA_TEST_DEBUG_PRINT(msg)+#   define CESA_TEST_DEBUG_CODE(code)++#endif /* CESA_TEST_DEBUG */++int                 cesaExpReqId=0;+int                 cesaCbIter=0;++int                 cesaIdx;+int                 cesaIteration;+int                 cesaRateSize;+int                 cesaReqSize;+unsigned long       cesaTaskId;+int                 cesaBufNum;+int                 cesaBufSize;+int                 cesaCheckOffset;+int                 cesaCheckSize;+int                 cesaCheckMode;+int                 cesaTestIdx;+int                 cesaCaseIdx;+++MV_U32      cesaTestIsrCount = 0;+MV_U32      cesaTestIsrMissCount = 0;++MV_U32      cesaCryptoError = 0;+MV_U32      cesaReqIdError  = 0;+MV_U32      cesaError = 0;++char*       cesaHexBuffer = NULL;++char*       cesaBinBuffer = NULL;+char*       cesaExpBinBuffer = NULL;++char*       cesaInputHexStr  = NULL;+char*       cesaOutputHexStr = NULL;++MV_BUF_INFO         cesaReqBufs[CESA_DEF_REQ_SIZE];++MV_CESA_COMMAND*    cesaCmdRing;+MV_CESA_RESULT      cesaResult;++int                 cesaTestFull = 0;++MV_BOOL             cesaIsReady = MV_FALSE;+MV_U32              cesaCycles = 0;+MV_U32              cesaBeginTicks = 0;+MV_U32              cesaEndTicks = 0;+MV_U32              cesaRate = 0;+MV_U32              cesaRateAfterDot = 0;++void 		    *cesaTestOSHandle = NULL;++enum+{+    CESA_FAST_CHECK_MODE = 0,+    CESA_FULL_CHECK_MODE,+    CESA_NULL_CHECK_MODE,+    CESA_SHOW_CHECK_MODE,+    CESA_SW_SHOW_CHECK_MODE,+    CESA_SW_NULL_CHECK_MODE,++    CESA_MAX_CHECK_MODE+};++enum+{+    DES_TEST_TYPE         = 0,+    TRIPLE_DES_TEST_TYPE  = 1,+    AES_TEST_TYPE         = 2,+    MD5_TEST_TYPE         = 3,+    SHA_TEST_TYPE         = 4,+    COMBINED_TEST_TYPE    = 5,++    MAX_TEST_TYPE+};++/* Tests data base */+typedef struct+{+    short           sid;+    char            cryptoAlgorithm;    /* DES/3DES/AES */+    char            cryptoMode;         /* ECB or CBC */+    char            macAlgorithm;       /* MD5 / SHA1 */+    char            operation;          /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */+    char            direction;          /* ENCODE(SIGN)/DECODE(VERIFY) */+    unsigned char*  pCryptoKey;+    int             cryptoKeySize;+    unsigned char*  pMacKey;+    int             macKeySize;+    const char*     name;++} MV_CESA_TEST_SESSION;++typedef struct+{+    MV_CESA_TEST_SESSION*   pSessions;+    int                     numSessions;++} MV_CESA_TEST_DB_ENTRY;++typedef struct+{+    char*           plainHexStr;+    char*           cipherHexStr;+    unsigned char*  pCryptoIV;+    int             cryptoLength;+    int             macLength;+    int             digestOffset;++} MV_CESA_TEST_CASE;++typedef struct+{+    int     size;+    const char* outputHexStr;++} MV_CESA_SIZE_TEST;++static unsigned char    cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,+                                        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,+                                        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};++static unsigned char    cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};+static unsigned char    iv1[]        = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};+++static unsigned char    cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,+                                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};++static unsigned char    cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,+                                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,+                                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};++static unsigned char    cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,+                                        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,+                                        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,+                                        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};++static unsigned char    cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,+                                        0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};+++static unsigned char    key3des1[]   = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,+                                        0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,+                                        0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};++/*  Input ASCII string: The quick brown fox jump  */+static char  plain3des1[]           =   "54686520717566636B2062726F776E20666F78206A756D70";+static char  cipher3des1[]          =   "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";++static unsigned char    key3des2[]  = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,+                                       0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,+                                       0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};++static unsigned char    iv3des2[]   = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};++static char  plain3des2[]           = "326a494cd33fe756";++static char  cipher3desCbc2[]       = "8e29f75ea77e5475"+                                      "b22b8d66de970692";++static unsigned char    key3des3[]  = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,+                                       0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,+                                       0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};++static unsigned char    iv3des3[]   = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};++static char  plain3des3[]           = "84401f78fe6c10876d8ea23094ea5309";++static char  cipher3desCbc3[]       = "3d1de3cc132e3b65"+                                      "7b1f7c7e3b1c948ebd04a75ffba7d2f5";++static unsigned char    iv5[]        = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,+                                        0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};++static unsigned char    aesCtrKey[]  = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,+                                        0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};++static unsigned char    mdKey1[]     = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,+                                        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};++static unsigned char    mdKey2[]     = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,+                                        0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};++static unsigned char    shaKey1[]    = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,+                                        0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,+                                        0x0b, 0x0b, 0x0b, 0x0b};++static unsigned char    shaKey2[]    = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,+                                        0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,+                                        0xaa, 0xaa, 0xaa, 0xaa};++static unsigned char    mdKey4[]     = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+                                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};++static unsigned char    shaKey4[]    = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+                                        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,+                                        0x11, 0x12, 0x13, 0x14};+++static MV_CESA_TEST_SESSION   desTestSessions[] =+{+/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),+             NULL, 0,+             "DES ECB encode",+        },+/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),+             NULL, 0,+             "DES ECB decode",+        },+/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),+             NULL, 0,+             "DES CBC encode"+        },+/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),+             NULL, 0,+             "DES CBC decode"+        },+/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0, NULL, 0,+              "NULL Crypto Algorithm encode"+        },+};+++static MV_CESA_TEST_SESSION   tripleDesTestSessions[] =+{+/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             NULL, 0,+             "3DES ECB encode",+        },+/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             NULL, 0,+             "3DES ECB decode",+        },+/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             NULL, 0,+             "3DES CBC encode"+        },+/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             NULL, 0,+             "3DES CBC decode"+        },+/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             key3des1, sizeof(key3des1),+             NULL, 0,+             "3DES ECB encode"+        },+/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             key3des2, sizeof(key3des2),+             NULL, 0,+             "3DES ECB encode"+        },+/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             key3des3, sizeof(key3des3),+             NULL, 0,+             "3DES ECB encode"+        },+};+++static MV_CESA_TEST_SESSION   aesTestSessions[] =+{+/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),+             NULL, 0,+             "AES-128 ECB encode"+        },+/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),+             NULL, 0,+             "AES-128 ECB decode"+        },+/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),+             NULL, 0,+             "AES-128 CBC encode"+        },+/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),+             NULL, 0,+             "AES-128 CBC decode"+        },+/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),+             NULL, 0,+             "AES-192 ECB encode"+        },+/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),+             NULL, 0,+             "AES-192 ECB decode"+        },+/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),+             NULL, 0,+             "AES-256 ECB encode"+        },+/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_DECODE,+             cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),+             NULL, 0,+             "AES-256 ECB decode"+        },+/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,+             MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,+             MV_CESA_DIR_ENCODE,+             aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),+             NULL, 0,+             "AES-128 CTR encode"+        },+};+++static MV_CESA_TEST_SESSION   md5TestSessions[] =+{+/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             mdKey1, sizeof(mdKey1),+             "HMAC-MD5 Generate Signature"+        },+/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_DECODE,+             NULL, 0,+             mdKey1, sizeof(mdKey1),+             "HMAC-MD5 Verify Signature"+        },+/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             mdKey2, sizeof(mdKey2),+             "HMAC-MD5 Generate Signature"+        },+/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_DECODE,+             NULL, 0,+             mdKey2, sizeof(mdKey2),+             "HMAC-MD5 Verify Signature"+        },+/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             mdKey4, sizeof(mdKey4),+             "HMAC-MD5 Generate Signature"+        },+/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             NULL, 0,+             "HASH-MD5 Generate Signature"+        },+};+++static MV_CESA_TEST_SESSION   shaTestSessions[] =+{+/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             shaKey1, sizeof(shaKey1),+             "HMAC-SHA1 Generate Signature"+        },+/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_DECODE,+             NULL, 0,+             shaKey1, sizeof(shaKey1),+             "HMAC-SHA1 Verify Signature"+        },+/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             shaKey2, sizeof(shaKey2),+             "HMAC-SHA1 Generate Signature"+        },+/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_DECODE,+             NULL, 0,+             shaKey2, sizeof(shaKey2),+             "HMAC-SHA1 Verify Signature"+        },+/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             shaKey4, sizeof(shaKey4),+             "HMAC-SHA1 Generate Signature"+        },+/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,+             MV_CESA_DIR_ENCODE,+             NULL, 0,+             NULL, 0,+             "HASH-SHA1 Generate Signature"+        },+};++static MV_CESA_TEST_SESSION   combinedTestSessions[] =+{+/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, MV_CESA_DES_KEY_LENGTH,+             mdKey4, sizeof(mdKey4),+             "DES + MD5 encode"+        },+/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, MV_CESA_DES_KEY_LENGTH,+             shaKey4, sizeof(shaKey4),+             "DES + SHA1 encode"+        },+/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             mdKey4, sizeof(mdKey4),+             "3DES + MD5 encode"+        },+/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             shaKey4, sizeof(shaKey4),+             "3DES + SHA1 encode"+        },+/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             mdKey4, sizeof(mdKey4),+             "3DES CBC + MD5 encode"+        },+/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             shaKey4, sizeof(shaKey4),+             "3DES CBC + SHA1 encode"+        },+/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),+             mdKey4, sizeof(mdKey4),+             "AES-128 CBC + MD5 encode"+        },+/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,+             MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,+             MV_CESA_DIR_ENCODE,+             cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),+             shaKey4, sizeof(shaKey4),+             "AES-128 CBC + SHA1 encode"+        },+/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,+             MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,+             MV_CESA_DIR_DECODE,+             cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),+             mdKey4, sizeof(mdKey4),+             "HMAC-MD5 + 3DES decode"+        },+};+++static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =+{+    { desTestSessions,       sizeof(desTestSessions)/sizeof(desTestSessions[0]) },+    { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },+    { aesTestSessions,       sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },+    { md5TestSessions,       sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },+    { shaTestSessions,       sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },+    { combinedTestSessions,  sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },+    { NULL,                  0 }+};+++char  cesaNullPlainHexText[]   = "000000000000000000000000000000000000000000000000";++char  cesaPlainAsciiText[]     = "Now is the time for all ";+char  cesaPlainHexEbc[]        = "4e6f77206973207468652074696d6520666f7220616c6c20";+char  cesaCipherHexEcb[]       = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";+char  cesaPlainHexCbc[]        = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";+char  cesaCipherHexCbc[]       = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";++char  cesaAesPlainHexEcb[]     = "000102030405060708090a0b0c0d0e0f";+char  cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";+char  cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";+char  cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";++char  cesaAsciiStr1[]          = "Hi There";+char  cesaDataHexStr1[]        = "4869205468657265";+char  cesaHmacMd5digestHex1[]  = "9294727a3638bb1c13f48ef8158bfc9d";+char  cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";+char  cesaDataAndMd5digest1[]  = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";+char  cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";++char  cesaAesPlainText[]       = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"+                                 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"+                                 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"+                                 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";++char  cesaAes128CipherCbc[]    = "c30e32ffedc0774e6aff6af0869f71aa"+                                 "0f3af07a9a31a9c684db207eb0ef8e4e"+                                 "35907aa632c3ffdf868bb7b29d3d46ad"+                                 "83ce9f9a102ee99d49a53e87f4c3da55";++char  cesaAesIvPlainText[]     = "8ce82eefbea0da3c44699ed7db51b7d9"+                                 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"+                                 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"+                                 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"+                                 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";++char  cesaAes128IvCipherCbc[]  = "8ce82eefbea0da3c44699ed7db51b7d9"+                                 "c30e32ffedc0774e6aff6af0869f71aa"+                                 "0f3af07a9a31a9c684db207eb0ef8e4e"+                                 "35907aa632c3ffdf868bb7b29d3d46ad"+                                 "83ce9f9a102ee99d49a53e87f4c3da55";++char  cesaAesCtrPlain[]        = "00E0017B27777F3F4A1786F000000001"+                                 "000102030405060708090A0B0C0D0E0F"+                                 "101112131415161718191A1B1C1D1E1F"+                                 "20212223";++char  cesaAesCtrCipher[]       = "00E0017B27777F3F4A1786F000000001"+                                 "C1CF48A89F2FFDD9CF4652E9EFDB72D7"+                                 "4540A42BDE6D7836D59A5CEAAEF31053"+                                 "25B2072F";++++/* Input cesaHmacHex3 is '0xdd' repeated 50 times */+char  cesaHmacMd5digestHex3[]  = "56be34521d144c88dbb8c733f0e8b3f6";+char  cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";+char  cesaDataHexStr3[50*2+1]          = "";+char  cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";+char  cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";++/* Ascii string is "abc" */+char hashHexStr3[] = "616263";+char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";+char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";++char hashHexStr80[]     = "31323334353637383930"+                          "31323334353637383930"+                          "31323334353637383930"+                          "31323334353637383930"+                          "31323334353637383930"+                          "31323334353637383930"+                          "31323334353637383930"+                          "31323334353637383930";++char hashMd5digest80[]           = "57edf4a22be3c955ac49da2e2107b67a";++char tripleDesThenMd5digest80[]  = "b7726a03aad490bd6c5a452a89a1b271";+char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";++char cbc3desThenMd5digest80[]    = "6f463057e1a90e0e91ae505b527bcec0";+char cbc3desThenSha1digest80[]   = "1b002ed050be743aa98860cf35659646bb8efcc0";++char cbcAes128ThenMd5digest80[]  = "6b6e863ac5a71d15e3e9b1c86c9ba05f";+char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";+++static MV_CESA_TEST_CASE  cesaTestCases[] =+{+ /*     plainHexStr          cipherHexStr               IV    crypto  mac     digest */+ /*                                                           Length  Length  Offset */+ /*0*/ { NULL,               NULL,                      NULL,   0,      0,      -1  },+ /*1*/ { cesaPlainHexEbc,    cesaCipherHexEcb,          NULL,   24,     0,      -1  },+ /*2*/ { cesaPlainHexCbc,    cesaCipherHexCbc,          NULL,   24,     0,      -1  },+ /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb,    NULL,   16,     0,      -1  },+ /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb,    NULL,   16,     0,      -1  },+ /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb,    NULL,   16,     0,      -1  },+ /*6*/ { cesaDataHexStr1,    cesaHmacMd5digestHex1,     NULL,   0,      8,      -1  },+ /*7*/ { NULL,               cesaDataAndMd5digest1,     NULL,   0,      8,      -1  },+ /*8*/ { cesaDataHexStr3,    cesaHmacMd5digestHex3,     NULL,   0,      50,     -1  },+ /*9*/ { NULL,               cesaDataAndMd5digest3,     NULL,   0,      50,     -1  },+/*10*/ { cesaAesPlainText,   cesaAes128IvCipherCbc,     iv5,    64,     0,      -1  },+/*11*/ { cesaDataHexStr1,    cesaHmacSha1digestHex1,    NULL,   0,      8,      -1  },+/*12*/ { NULL,               cesaDataAndSha1digest1,    NULL,   0,      8,      -1  },+/*13*/ { cesaDataHexStr3,    cesaHmacSha1digestHex3,    NULL,   0,      50,     -1  },+/*14*/ { NULL,               cesaDataAndSha1digest3,    NULL,   0,      50,     -1  },+/*15*/ { hashHexStr3,        hashMd5digest3,            NULL,   0,      3,      -1  },+/*16*/ { hashHexStr3,        hashSha1digest3,           NULL,   0,      3,      -1  },+/*17*/ { hashHexStr80,       tripleDesThenMd5digest80,  NULL,   80,     80,     -1  },+/*18*/ { hashHexStr80,       tripleDesThenSha1digest80, NULL,   80,     80,     -1  },+/*19*/ { hashHexStr80,       cbc3desThenMd5digest80,    iv1,    80,     80,     -1  },+/*20*/ { hashHexStr80,       cbc3desThenSha1digest80,   iv1,    80,     80,     -1  },+/*21*/ { hashHexStr80,       cbcAes128ThenMd5digest80,  iv5,    80,     80,     -1  },+/*22*/ { hashHexStr80,       cbcAes128ThenSha1digest80, iv5,    80,     80,     -1  },+/*23*/ { cesaAesCtrPlain,    cesaAesCtrCipher,          NULL,   36,     0,      -1  },+/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc,     NULL,   64,     0,      -1  },+/*25*/ { plain3des1,         cipher3des1,               NULL,   0,      0,      -1  },+/*26*/ { plain3des2,         cipher3desCbc2,            iv3des2,0,      0,      -1  },+/*27*/ { plain3des3,         cipher3desCbc3,            iv3des3,0,      0,      -1  },+};+++/* Key         = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,+ *               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa+ * Input 0xdd repeated "size" times+ */+static MV_CESA_SIZE_TEST     mdMultiSizeTest302[] =+{+    { 80,   "7a031a640c14a4872814930b1ef3a5b2" },+    { 512,  "5488e6c5a14dc72a79f28312ca5b939b" },+    { 1000, "d00814f586a8b78a05724239d2531821" },+    { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },+    { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },+    { 1003, "5972ab64a4f265ee371dac2f2f137f90" },+    { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },+    { 1005, "e082790b4857fcfc266e92e59e608814" },+    { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },+    { 1336, "e42edcce57d0b75b01aa09d71427948b" },+    { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },+    { 1399, "0f44d793e744b24d53f44f295082ee8c" },+    { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },+    { 1401, "e913858b484cbe2b384099ea88d8855b" },+    { 1402, "d9848a164af53620e0540c1d7d87629e" },+    { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },+    { 1404, "12edd4f609416e3c936170360561b064" },+    { 1405, "7fc912718a05446395345009132bf562" },+    { 1406, "882f17425e579ff0d85a91a59f308aa0" },+    { 1407, "005cae408630a2fb5db82ad9db7e59da" },+    { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },+    { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },+    { 2048, "67caf64475650732def374ebb8bde3fd" },+    { 2049, "6c84f11f472825f7e6cd125c2981884b" },+    { 2050, "8999586754a73a99efbe4dbad2816d41" },+    { 2051, "ba6946b610e098d286bc81091659dfff" },+    { 2052, "d0afa01c92d4d13def2b024f36faed83" },+    { 3072, "61d8beac61806afa2585d74a9a0e6974" },+    { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },+    { 3075, "ea4a6929be67e33e61ff475369248b73" },+    { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },+    { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },+    { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },+    { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },+    { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },+    { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },+    { 6528, "b1d707b027354aca152c45ee559ccd3f" },+    { 8192, "c600ea4429ac47f9941f09182166e51a" },+    {16384, "16e8754bfbeb4c649218422792267a37" },+    {18432, "0fd0607521b0aa8b52219cfbe215f63e" },+    { 0, NULL },+};++/* Key         = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ */+static MV_CESA_SIZE_TEST     mdMultiSizeTest304[] =+{+    { 80,   "a456c4723fee6068530af5a2afa71627" },+    { 512,  "f85c2a2344f5de68b432208ad13e5794" },+    { 1000, "35464d6821fd4a293a41eb84e274c8c5" },+    { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },+    { 1002, "5664f71800c011cc311cb6943339c1b8" },+    { 1003, "779c723b044c585dc7802b13e8501bdc" },+    { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },+    { 1005, "d5f978954f5c38529d1679d2b714f068" },+    { 1006, "cd3efc827ce628b7281b72172693abf9" },+    { 1336, "6f04479910785878ae6335b8d1e87edf" },+    { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },+    { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },+    { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },+    { 1401, "3a06f3582033a66a4e57e0603ce94e74" },+    { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },+    { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },+    { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },+    { 1405, "d1487bd42f6edd9b4dab316631159221" },+    { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },+    { 1407, "3224a06639db70212a0cd1ae1fcc570a" },+    { 1408, "a9e13335612c0356f5e2c27086e86c43" },+    { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },+    { 2048, "396905c9b961cd0f6152abfb69c4449c" },+    { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },+    { 2050, "3a2b4823bc4d0415656550226a63e34a" },+    { 2051, "dec60580d406c782540f398ad0bcc7e0" },+    { 2052, "32f76610a14310309eb748fe025081bf" },+    { 3072, "45edc1a42bf9d708a621076b63b774da" },+    { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },+    { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },+    { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },+    { 4052, "81976bcaeb274223983996c137875cb8" },+    { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },+    { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },+    { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },+    { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },+    { 6528, "216f44f23047cfee03a7a64f88f9a995" },+    { 8192, "ac7a993b2cad54879dba1bde63e39097" },+    { 8320, "55ed7be9682d6c0025b3221a62088d08" },+    {16384, "c6c722087653b62007aea668277175e5" },+    {18432, "f1faca8e907872c809e14ffbd85792d6" },+    { 0, NULL },+};++/* HASH-MD5+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ *               repeated "size" times+ */+static MV_CESA_SIZE_TEST     mdMultiSizeTest305[] =+{+    { 80,   "57edf4a22be3c955ac49da2e2107b67a" },+    { 512,  "c729ae8f0736cc377a9767a660eaa04e" },+    { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },+    { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },+    { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },+    { 1003, "961753017feee04c9b93a8e51658a829" },+    { 1004, "dd68c4338608dcc87807a711636bf2af" },+    { 1005, "e338d567d3ce66bf69ada29658a8759b" },+    { 1006, "443c9811e8b92599b0b149e8d7ec700a" },+    { 1336, "89a98511706008ba4cbd0b4a24fa5646" },+    { 1344, "335a919805f370b9e402a62c6fe01739" },+    { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },+    { 1400, "6b695c240d2dffd0dffc99459ca76db6" },+    { 1401, "49590f61298a76719bc93a57a30136f5" },+    { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },+    { 1403, "37073a02ab00ecba2645c57c228860db" },+    { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },+    { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },+    { 1406, "4b6695772a4c66313fa4871017d05f36" },+    { 1407, "d1539b97fbfda1c075624e958de19c5b" },+    { 1408, "b801b9b69920907cd018e8063092ede9" },+    { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },+    { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },+    { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },+    { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },+    { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },+    { 2052, "dd44a0d128b63d4b5cccd967906472d7" },+    { 3072, "37d158e33b21390822739d13db7b87fe" },+    { 3074, "aef3b209d01d39d0597fe03634bbf441" },+    { 3075, "335ffb428eabf210bada96d74d5a4012" },+    { 4048, "2434c2b43d798d2819487a886261fc64" },+    { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },+    { 4058, "856781f85616c341c3533d090c1e1e84" },+    { 6144, "e5d134c652c18bf19833e115f7a82e9b" },+    { 6150, "a09a353be7795fac2401dac5601872e6" },+    { 6400, "08b9033ac6a1821398f50af75a2dbc83" },+    { 6528, "3d47aa193a8540c091e7e02f779e6751" },+    { 8192, "d3164e710c0626f6f395b38f20141cb7" },+    { 8320, "b727589d9183ff4e8491dd24466974a3" },+    {16384, "3f54d970793d2274d5b20d10a69938ac" },+    {18432, "f558511dcf81985b7a1bb57fad970531" },+    { 0, NULL },+};+++/* Key         = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,+ *               0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa+ *               0xaa, 0xaa, 0xaa, 0xaa+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ */+static MV_CESA_SIZE_TEST     shaMultiSizeTest402[] =+{+    { 80,   "e812f370e659705a1649940d1f78cd7af18affd3" },+    { 512,  "e547f886b2c15d995ed76a8a924cb408c8080f66" },+    { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },+    { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },+    { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },+    { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },+    { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },+    { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },+    { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },+    { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },+    { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },+    { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },+    { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },+    { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },+    { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },+    { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },+    { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },+    { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },+    { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },+    { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },+    { 1408, "3987511182b18473a564436003139b808fa46343" },+    { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },+    { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },+    { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },+    { 2050, "8831939904009338de10e7fa670847041387807d" },+    { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },+    { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },+    { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },+    { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },+    { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },+    { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },+    { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },+    { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },+    { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },+    { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },+    { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },+    { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },+    { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },+    { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },+    {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },+    {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },+    { 0, NULL },+};++/* Key         = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ *               0x11, 0x12, 0x13, 0x14+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ */+static MV_CESA_SIZE_TEST     shaMultiSizeTest404[] =+{+    { 80,   "beaf20a34b06a87558d156c0949bc3957d40222e" },+    { 512,  "3353955358d886bc2940a3c7f337ff7dafb59c7b" },+    { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },+    { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },+    { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },+    { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },+    { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },+    { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },+    { 1006, "6d875319049314b61855101a647b9ba3313428e6" },+    { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },+    { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },+    { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },+    { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },+    { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },+    { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },+    { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },+    { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },+    { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },+    { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },+    { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },+    { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },+    { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },+    { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },+    { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },+    { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },+    { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },+    { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },+    { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },+    { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },+    { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },+    { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },+    { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },+    { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },+    { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },+    { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },+    { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },+    { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },+    { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },+    { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },+    {16384, "62e093fde467f0748087beea32e9af97d5c61241" },+    {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },+    { 0, NULL },+};++/* HASH-SHA1+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ *               repeated "size" times+ */+static MV_CESA_SIZE_TEST     shaMultiSizeTest405[] =+{+    { 80,   "50abf5706a150990a08b2c5ea40fa0e585554732" },+    { 512,  "f14516a08948fa27917a974d219741a697ba0087" },+    { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },+    { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },+    { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },+    { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },+    { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },+    { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },+    { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },+    { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },+    { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },+    { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },+    { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },+    { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },+    { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },+    { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },+    { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },+    { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },+    { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },+    { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },+    { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },+    { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },+    { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },+    { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },+    { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },+    { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },+    { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },+    { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },+    { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },+    { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },+    { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },+    { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },+    { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },+    { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },+    { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },+    { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },+    { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },+    { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },+    { 8320, "91606a31b46afeaac965cecf87297e791b211013" },+    {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },+    {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },+    { 0, NULL },+};++/* CryptoKey   = 0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef;+ * MacKey      = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed+ */+static MV_CESA_SIZE_TEST     tripleDesMdMultiSizeTest502[] =+{+    {   64, "9586962a2aaaef28803dec2e17807a7f" },+    {   80, "b7726a03aad490bd6c5a452a89a1b271" },+    {  352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },+    {  512, "0f9decb11ab40fe86f4d4d9397bc020e" },+    { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },+    { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },+    { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },+    { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },+    { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },+    { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },+    { 3072, "731204d2d90c4b36ae41f5e1fb874288" },+    { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },+    { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },+    { 6400, "44e4613496ba622deb0e7cb768135a2f" },+    { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },+    { 8192, "d581780b7163138a0f412be681457d82" },+    {16384, "03b8ac05527faaf1bed03df149c65ccf" },+    {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },+    { 0, NULL },+};+++/* CryptoKey   = 0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef;+ * MacKey      = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ *               0x11, 0x12, 0x13, 0x14+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed+ */+static MV_CESA_SIZE_TEST     tripleDesShaMultiSizeTest503[] =+{+    {   64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },+    {   80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },+    {  352, "4b91864c7ff629bdff75d9726421f76705452aaf" },+    {  512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },+    { 1000, "463661c30300be512a9df40904f0757cde5f1141" },+    { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },+    { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },+    { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },+    { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },+    { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },+    { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },+    { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },+    { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },+    { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },+    { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },+    { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },+    {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },+    {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },+    { 0, NULL },+};++/* CryptoKey   = 0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef+ * IV          = 0x12345678, 0x90abcdef+ * MacKey      = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed+ */+static MV_CESA_SIZE_TEST     cbc3desMdMultiSizeTest504[] =+{+    {   64, "8d10e00802460ede0058c139ba48bd2d" },+    {   80, "6f463057e1a90e0e91ae505b527bcec0" },+    {  352, "4938d48bdf86aece2c6851e7c6079788" },+    {  512, "516705d59f3cf810ebf2a13a23a7d42e" },+    { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },+    { 1336, "44af60087b74ed07950088efbe3b126a" },+    { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },+    { 1400, "6804ea640e29b9cd39e08bc37dbce734" },+    { 1408, "4fb436624b02516fc9d1535466574bf9" },+    { 2048, "c909b0985c423d8d86719f701e9e83db" },+    { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },+    { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },+    { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },+    { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },+    { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },+    { 8192, "afe101fbe745bb449ae4f50d10801456" },+    {16384, "9741706d0b1c923340c4660ff97cacdf" },+    {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },+    { 0, NULL },+};+++/* CryptoKey   = 0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef;+ * IV          = 0x12345678, 0x90abcdef+ * MacKey      = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ *               0x11, 0x12, 0x13, 0x14+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ * Note: only sizes aligned to 3DES block size (8 bytes) allowed+ */+static MV_CESA_SIZE_TEST     cbc3desShaMultiSizeTest505[] =+{+    {   64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },+    {   80, "1b002ed050be743aa98860cf35659646bb8efcc0" },+    {  352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },+    {  512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },+    { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },+    { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },+    { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },+    { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },+    { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },+    { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },+    { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },+    { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },+    { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },+    { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },+    { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },+    { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },+    {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },+    {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },+    { 0, NULL },+};+++/* CryptoKey   = 0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef+ * IV          = 0x12345678, 0x90abcdef+ * MacKey      = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ * Note: only sizes aligned to AES block size (16 bytes) allowed+ */+static MV_CESA_SIZE_TEST     cbcAes128md5multiSizeTest506[] =+{+    {   16, "7ca4c2ba866751598720c5c4aa0d6786" },+    {   64, "7dba7fb988e80da609b1fea7254bced8" },+    {   80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },+    {  352, "a1ceb9c2e3021002400d525187a9f38c" },+    {  512, "596c055c1c55db748379223164075641" },+    { 1008, "f920989c02f3b3603f53c99d89492377" },+    { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },+    { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },+    { 2048, "a917f0099c69eb94079a8421714b6aad" },+    { 3072, "693cd5033d7f5391d3c958519fa9e934" },+    { 4048, "139dca91bcff65b3c40771749052906b" },+    { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },+    { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },+    { 6528, "ad876f6297186a7be1f1b907ed860eda" },+    { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },+    {16384, "60fda559c74f91df538100c9842f2f15" },+    {18432, "4a3eb1cba1fa45f3981270953f720c42" },+    { 0, NULL },+};+++/* CryptoKey   = 0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef,+ *               0x01234567, 0x89abcdef;+ * IV          = 0x12345678, 0x90abcdef+ * MacKey      = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,+ *               0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10+ *               0x11, 0x12, 0x13, 0x14+ * InputHexStr = "31323334353637383930" (ASCII = "1234567890")+ * Note: only sizes aligned to AES block size (16 bytes) allowed+ */+static MV_CESA_SIZE_TEST     cbcAes128sha1multiSizeTest507[] =+{+    {   16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },+    {   64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },+    {   80, "13558472d1fc1c90dffec6e5136c7203452d509b" },+    {  352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },+    {  512, "096874951a77fbbf333e49d80c096ee2016e09bd" },+    { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },+    { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },+    { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },+    { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },+    { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },+    { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },+    { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },+    { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },+    { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },+    { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },+    {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },+    {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },+    { 0, NULL },+};+++void    cesaTestPrintStatus(void);+++/*------------------------- LOCAL FUNCTIONs ---------------------------------*/+MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,+                  MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);+MV_STATUS testClose(int idx);+MV_STATUS testOpen(int idx);+void close_session(int sid);+void cesaTestCheckReady(const MV_CESA_RESULT *r);+void cesaCheckReady(MV_CESA_RESULT* r);+void printTestResults(int idx, MV_STATUS status, int checkMode);+void cesaLastResult(void);+void cesaTestPrintReq(int req, int offset, int size);++void cesaTestPrintStatus(void);+void cesaTestPrintSession(int idx);+void sizeTest(int testIdx, int iter, int checkMode);+void multiTest(int iter, int reqSize, int checkMode);+void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);+void multiSizeTest(int idx, int iter, int checkMode, char* inputData);+void cesaTest(int iter, int reqSize, int checkMode);+void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);+void combiTest(int iter, int reqSize, int checkMode);+void shaTest(int iter, int reqSize, int checkMode);+void mdTest(int iter, int reqSize, int checkMode);+void aesTest(int iter, int reqSize, int checkMode);+void tripleDesTest(int iter, int reqSize, int checkMode);+void desTest(int iter, int reqSize, int checkMode);+void cesaTestStop(void);+MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);+void cesaTestStart(int bufNum, int bufSize);+++static MV_U32      getRate(MV_U32* remainder)+{+    MV_U32     kBits, milliSec, rate;++    milliSec = 0;+    if( (cesaEndTicks - cesaBeginTicks) > 0)+    {+        milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);+    }+    if(milliSec == 0)+    {+        if(remainder != NULL)+            *remainder = 0;+        return 0;+    }++    kBits = (cesaIteration*cesaRateSize*8)/1000;+    rate = kBits/milliSec;+    if(remainder != NULL)+        *remainder = ((kBits % milliSec)*10)/milliSec;++    return rate;+}++static char*    extractMbuf(MV_CESA_MBUF *pMbuf,+                            int offset, int size, char* hexStr)+{+    mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);+    mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);++    return hexStr;+}++static MV_BOOL  cesaCheckMbuf(MV_CESA_MBUF *pMbuf,+                          const char* hexString, int offset,+                          int checkSize)+{+    MV_BOOL     isFailed = MV_FALSE;+    MV_STATUS   status;+    int         size = strlen(hexString)/2;+    int         checkedSize = 0;+/*+    mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",+                pMbuf, offset, checkSize, pMbuf->mbufSize);+*/+    if(pMbuf->mbufSize < (checkSize + offset))+    {+        mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",+                    checkSize, offset, pMbuf->mbufSize);+        return MV_TRUE;+    }+    status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);+    if(status != MV_OK)+    {+        mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",+                    checkSize, pMbuf, cesaBinBuffer);+        return MV_TRUE;+    }+/*+    mvDebugMemDump(cesaBinBuffer, size, 1);+*/+    mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);++    /* Compare buffers */+    while(checkSize > checkedSize)+    {+        size = MV_MIN(size, (checkSize - checkedSize));+        if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)+        {+            mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",+                        checkSize, size, checkedSize);+            mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);+            mvDebugMemDump(cesaExpBinBuffer, size, 1);++            isFailed = MV_TRUE;+            break;+        }+        checkedSize += size;+    }++    return isFailed;+}++static MV_STATUS    cesaSetMbuf(MV_CESA_MBUF *pMbuf,+                        const char* hexString,+                        int offset, int reqSize)+{+    MV_STATUS   status = MV_OK;+    int         copySize, size = strlen(hexString)/2;++    mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);++    copySize = 0;+    while(reqSize > copySize)+    {+        size = MV_MIN(size, (reqSize - copySize));++        status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);+        if(status != MV_OK)+        {+            mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",+                        copySize, reqSize);+            break;+        }+        copySize += size;+    }+    pMbuf->mbufSize = offset+copySize;+    return status;+}++static  MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)+{+    int                 testIdx, dbIdx = idx/100;++    if(dbIdx > MAX_TEST_TYPE)+    {+        mvOsPrintf("Wrong index %d - No such test type\n", idx);+        return NULL;+    }+    testIdx = idx % 100;++    if(testIdx >= cesaTestsDB[dbIdx].numSessions)+    {+        mvOsPrintf("Wrong index %d - No such test\n", idx);+        return NULL;+    }+    if(pTestIdx != NULL)+        *pTestIdx = testIdx;++    return  cesaTestsDB[dbIdx].pSessions;+}++/* Debug */+void    cesaTestPrintReq(int req, int offset, int size)+{+    MV_CESA_MBUF*   pMbuf;++    mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n", +                req, offset, size);+    mvDebugMemDump(cesaCmdRing, 128, 4);++    pMbuf = cesaCmdRing[req].pSrc;+    mvCesaDebugMbuf("src", pMbuf, offset,size);+    pMbuf = cesaCmdRing[req].pDst;+    mvCesaDebugMbuf("dst", pMbuf, offset, size);++    cesaTestPrintStatus();+}++void    cesaLastResult(void)+{+        mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",+                (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,+                cesaResult.retCode);+}++void    printTestResults(int idx, MV_STATUS status, int checkMode)+{+    int                     testIdx;+    MV_CESA_TEST_SESSION*   pTestSessions = getTestSessionDb(idx, &testIdx);++    if(pTestSessions == NULL)+        return;++    mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,+            cesaIteration, cesaReqSize);+    if( (status == MV_OK)      &&+        (cesaCryptoError == 0) &&+        (cesaError == 0)       &&+        (cesaReqIdError == 0) )+    {+        mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n", +                     cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);+    }+    else+    {+        mvOsPrintf("Failed, Status = 0x%x\n", status);+        if(cesaCryptoError > 0)+            mvOsPrintf("cryptoError : %d\n", cesaCryptoError);+        if(cesaReqIdError > 0)+            mvOsPrintf("reqIdError  : %d\n", cesaReqIdError);+        if(cesaError > 0)+            mvOsPrintf("cesaError  : %d\n", cesaError);+    }+    if(cesaTestIsrMissCount > 0)+        mvOsPrintf("cesaIsrMissed  : %d\n", cesaTestIsrMissCount);+}++void cesaCheckReady(MV_CESA_RESULT* r)+{+    int             reqId;+    MV_CESA_MBUF    *pMbuf;+    MV_BOOL         isFailed;++    cesaResult  =  *r;+    reqId = (int)cesaResult.pReqPrv;+    pMbuf = cesaCmdRing[reqId].pDst;++/*+    mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",+                    reqId, cesaCheckOffset, cesaCheckSize);+*/+    /* Check expected reqId */+    if(reqId != cesaExpReqId)+    {+        cesaReqIdError++;+/*+        mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",+                    cesaCbIter, cesaIteration, reqId, cesaExpReqId);+*/+    }+    else+    {+        if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||+            (cesaCheckMode == CESA_FAST_CHECK_MODE) )+        {+            if(cesaResult.retCode != MV_OK)+            {+                cesaError++;++                mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",+                            cesaCbIter, cesaIteration, reqId, cesaResult.retCode);+            }+            else+            {+                if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )+                {+                    /* Check expected output */++                    isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);+                    if(isFailed)+                    {+                        mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",+                                    cesaCbIter, cesaIteration, reqId);++                        CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",+                                    reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));++                        CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));++                        CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );++                        cesaCryptoError++;+                    }+                }+            }+        }+    }+    if(cesaCheckMode == CESA_SHOW_CHECK_MODE)+    {+        extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);+        mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);+    }++    cesaCbIter++;+    if(cesaCbIter >= cesaIteration)+    {+        cesaCbIter = 0;+        cesaExpReqId = 0;+        cesaIsReady = MV_TRUE;++        cesaEndTicks = CESA_TEST_TICK_GET();+        cesaRate = getRate(&cesaRateAfterDot);+    }+    else+    {+        cesaExpReqId = reqId + 1;+        if(cesaExpReqId == CESA_DEF_REQ_SIZE)+            cesaExpReqId = 0;+    }+}+++#ifdef MV_NETBSD+static int cesaTestReadyIsr(void *arg)+#else+#ifdef __KERNEL__+static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)+#endif+#ifdef MV_VXWORKS+void   cesaTestReadyIsr(void)+#endif+#endif+{+    MV_U32          cause;+    MV_STATUS       status;+    MV_CESA_RESULT  result;++    cesaTestIsrCount++;+    /* Clear cause register */+    cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);+    if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)+    {+        mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);+#ifdef MV_NETBSD+        return 0;+#else+#ifdef __KERNEL__+        return 1;+#else+        return;+#endif+#endif+    }++    MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);++    while(MV_TRUE)+    {+        /* Get Ready requests */+        status = mvCesaReadyGet(&result);+        if(status == MV_OK)+            cesaCheckReady(&result);++        break;+    }+    if( (cesaTestFull == 1) && (status != MV_BUSY) )+    {+        cesaTestFull = 0;+        CESA_TEST_WAKE_UP();+    }++#ifdef __KERNEL__+    return 1;+#endif+}++void+cesaTestCheckReady(const MV_CESA_RESULT *r)+{+	MV_CESA_RESULT result = *r;++	cesaCheckReady(&result);++	if (cesaTestFull == 1) {+		cesaTestFull = 0;+		CESA_TEST_WAKE_UP();+	}+}++static INLINE int   open_session(MV_CESA_OPEN_SESSION* pOs)+{+    MV_U16      sid;+    MV_STATUS   status;++    status = mvCesaSessionOpen(pOs, (short*)&sid);+    if(status != MV_OK)+    {+        mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",+                    status);+        return -1;+    }++    return  (int)sid;+}++void close_session(int sid)+{+    MV_STATUS   status;++    status = mvCesaSessionClose(sid);+    if(status != MV_OK)+    {+        mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",+                    sid, status);+    }+}++MV_STATUS testOpen(int idx)+{+    MV_CESA_OPEN_SESSION    os;+    int                     sid, i, testIdx;+    MV_CESA_TEST_SESSION*   pTestSession;+    MV_U16          digestSize = 0;++    pTestSession = getTestSessionDb(idx, &testIdx);+    if(pTestSession == NULL)+    {+        mvOsPrintf("Test %d is not exist\n", idx);+        return MV_BAD_PARAM;+    }+    pTestSession = &pTestSession[testIdx];++    if(pTestSession->sid != -1)+    {+        mvOsPrintf("Session for test %d already created: sid=%d\n",+                    idx, pTestSession->sid);+        return MV_OK;+    }++    os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;+    os.macMode = pTestSession->macAlgorithm;+    switch(os.macMode)+    {+        case MV_CESA_MAC_MD5:+        case MV_CESA_MAC_HMAC_MD5:+            digestSize = MV_CESA_MD5_DIGEST_SIZE;+            break;++        case MV_CESA_MAC_SHA1:+        case MV_CESA_MAC_HMAC_SHA1:+            digestSize = MV_CESA_SHA1_DIGEST_SIZE;+            break;++        case MV_CESA_MAC_NULL:+            digestSize = 0;+    }+    os.cryptoMode = pTestSession->cryptoMode;+    os.direction = pTestSession->direction;+    os.operation = pTestSession->operation;++    for(i=0; i<pTestSession->cryptoKeySize; i++)+        os.cryptoKey[i] = pTestSession->pCryptoKey[i];++    os.cryptoKeyLength = pTestSession->cryptoKeySize;++    for(i=0; i<pTestSession->macKeySize; i++)+        os.macKey[i] = pTestSession->pMacKey[i];++    os.macKeyLength = pTestSession->macKeySize;+    os.digestSize = digestSize;++    sid = open_session(&os);+    if(sid == -1)+    {+        mvOsPrintf("Can't open session for test %d: rc=0x%x\n",+                    idx, cesaResult.retCode);+        return cesaResult.retCode;+    }+    CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));+    pTestSession->sid = sid;+    return MV_OK;+}++MV_STATUS   testClose(int idx)+{+    int                     testIdx;+    MV_CESA_TEST_SESSION*   pTestSession;++    pTestSession = getTestSessionDb(idx, &testIdx);+    if(pTestSession == NULL)+    {+        mvOsPrintf("Test %d is not exist\n", idx);+        return MV_BAD_PARAM;+    }+    pTestSession = &pTestSession[testIdx];++    if(pTestSession->sid == -1)+    {+        mvOsPrintf("Test session %d is not opened\n", idx);+        return MV_NO_SUCH;+    }++    close_session(pTestSession->sid);+    pTestSession->sid = -1;++    return MV_OK;+}++MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,+             MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)+{+    int                 cmdReqId = 0;+    int                 i;+    MV_STATUS           rc = MV_OK;+    char                ivZeroHex[] = "0000";++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    if(pCmd == NULL)+    {+        mvOsPrintf("testCmd failed: pCmd=NULL\n");+        return MV_BAD_PARAM;+    }+    pCmd->sessionId = sid;++    cesaCryptoError = 0;+    cesaReqIdError = 0;+    cesaError = 0;+    cesaTestIsrMissCount = 0;+    cesaIsReady = MV_FALSE;+    cesaIteration = iter;++    if(cesaInputHexStr == NULL)+        cesaInputHexStr = cesaPlainHexEbc;++    for(i=0; i<CESA_DEF_REQ_SIZE; i++)+    {+        pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);+        if(pIV != NULL)+        {+            /* If IV from SA - set IV in Source buffer to zeros */+            cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);+            cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,+                        (cesaReqSize - pCmd->cryptoOffset));+        }+        else+        {+            cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);+        }+        pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);+        cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);++        memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));+    }++    if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)+    {+        MV_U8   pDigest[MV_CESA_MAX_DIGEST_SIZE];++        if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)+        {+            mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);+            mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",+                        cesaReqSize, pCmd->macLength);+            mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);+            return MV_OK;+        }+        if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)+        {+            mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);+            mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",+                        cesaReqSize, pCmd->macLength);+            mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);+            return MV_OK;+        }+    }++    cesaBeginTicks = CESA_TEST_TICK_GET();+    CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));+                     cesaTestTraceIdx = 0;+    );++    if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)+    {+        volatile MV_U8   pDigest[MV_CESA_MAX_DIGEST_SIZE];++        for(i=0; i<iter; i++)+        {+            if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)+            {+                mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);+            }+            if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)+            {+                mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);+            }+        }+        cesaEndTicks = CESA_TEST_TICK_GET();+        cesaRate = getRate(&cesaRateAfterDot);+        cesaIsReady = MV_TRUE;++        return MV_OK;+    }++    /*cesaTestIsrCount = 0;*/+    /*mvCesaDebugStatsClear();*/++#ifndef MV_NETBSD+    MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);+#endif++    for(i=0; i<iter; i++)+    {+        unsigned long flags;++        pCmd = &cesaCmdRing[cmdReqId];+        pCmd->pReqPrv = (void*)cmdReqId;++        CESA_TEST_LOCK(flags);++        rc = mvCesaAction(pCmd);+        if(rc == MV_NO_RESOURCE)+            cesaTestFull = 1;++        CESA_TEST_UNLOCK(flags);++        if(rc == MV_NO_RESOURCE)+        {+            CESA_TEST_LOCK(flags);+            CESA_TEST_WAIT( (cesaTestFull == 0), 100);+            CESA_TEST_UNLOCK(flags);+            if(cesaTestFull == 1)+            {+                mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",+                            i, iter, cesaTestFull);+                cesaTestFull = 0;+                return MV_TIMEOUT;+            }++            CESA_TEST_LOCK(flags);++            rc = mvCesaAction(pCmd);++            CESA_TEST_UNLOCK(flags);+        }+        if( (rc != MV_OK) && (rc != MV_NO_MORE) )+        {+            mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);+            return rc;+        }++        cmdReqId++;+        if(cmdReqId >= CESA_DEF_REQ_SIZE)+            cmdReqId = 0;++#ifdef MV_LINUX+        /* Reschedule each 16 requests */+        if( (i & 0xF) == 0)+            schedule();+#endif+    }+    return MV_OK;+}++void    cesaTestStart(int bufNum, int bufSize)+{+    int             i, j, idx;+    MV_CESA_MBUF    *pMbufSrc, *pMbufDst;+    MV_BUF_INFO     *pFragsSrc, *pFragsDst;+    char            *pBuf;+#ifndef MV_NETBSD+    int             numOfSessions, queueDepth;+    char            *pSram;+    MV_STATUS       status;+    MV_CPU_DEC_WIN  addrDecWin;+#endif++    cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);+    if(cesaCmdRing == NULL)+    {+        mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",+                sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);+        return;+    }+    memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);++    if(bufNum == 0)+        bufNum = CESA_DEF_BUF_NUM;++    if(bufSize == 0)+        bufSize = CESA_DEF_BUF_SIZE;++    cesaBufNum = bufNum;+    cesaBufSize = bufSize;+    mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",+                bufNum, bufSize);++    cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);+    if(cesaHexBuffer == NULL)+    {+        mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",+                    2*bufNum*bufSize);+        return;+    }+    memset(cesaHexBuffer, 0, (2*bufNum*bufSize));++    cesaBinBuffer = mvOsMalloc(bufNum*bufSize);+    if(cesaBinBuffer == NULL)+    {+        mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",+                    bufNum*bufSize);+        return;+    }+    memset(cesaBinBuffer, 0, (bufNum*bufSize));++    cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);+    if(cesaExpBinBuffer == NULL)+    {+        mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",+                    bufNum*bufSize);+        return;+    }+    memset(cesaExpBinBuffer, 0, (bufNum*bufSize));++    CESA_TEST_WAIT_INIT();++    pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);+    pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);++    pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);+    pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);++    if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||+        (pMbufDst == NULL) || (pFragsDst == NULL) )+    {+        mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");+        /* !!!! Dima cesaTestCleanup();*/+        return;+    }++    memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);+    memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);++    memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);+    memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);++    mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",+                pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);++    idx = 0;+    for(i=0; i<CESA_DEF_REQ_SIZE; i++)+    {+        pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,+				  &cesaReqBufs[i].bufPhysAddr,+				  &cesaReqBufs[i].memHandle);+		if(pBuf == NULL)+    	{+        	mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",+                    bufSize * bufNum * 2);+        	return;+    	}++        memset(pBuf, 0, bufSize * bufNum * 2);+        mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);+        if(pBuf == NULL)+        {+            mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",+                        bufSize * bufNum * 2, i);+            return;+        }++        cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;+        cesaReqBufs[i].bufSize =  bufSize * bufNum * 2;++        cesaCmdRing[i].pSrc = &pMbufSrc[i];+        cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];+        cesaCmdRing[i].pSrc->numFrags = bufNum;+        cesaCmdRing[i].pSrc->mbufSize = 0;++        cesaCmdRing[i].pDst = &pMbufDst[i];+        cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];+        cesaCmdRing[i].pDst->numFrags = bufNum;+        cesaCmdRing[i].pDst->mbufSize = 0;++        for(j=0; j<bufNum; j++)+        {+            cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;+            cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;+            pBuf += bufSize;+            cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;+            cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;+            pBuf += bufSize;+        }+        idx += bufNum;+    }++#ifndef MV_NETBSD+    if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)+        pSram = (char*)addrDecWin.addrWin.baseLow;+    else+    {+        mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");+        return;+    }++#ifdef MV_CESA_NO_SRAM+    pSram = mvOsMalloc(4*1024+8);+    if(pSram == NULL)+    {+        mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",+                4*1024+8);+        /* !!!! Dima cesaTestCleanup();*/+        return;+    }+    pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);+#endif /* MV_CESA_NO_SRAM */++    numOfSessions = CESA_DEF_SESSION_NUM;+    queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;++    status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);+    if(status != MV_OK)+    {+        mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);+        /* !!!! Dima cesaTestCleanup();*/+        return;+    }+#endif /* !MV_NETBSD */++    /* Prepare data for tests */+    for(i=0; i<50; i++)+        strcat((char*)cesaDataHexStr3, "dd");++    strcpy((char*)cesaDataAndMd5digest3,  cesaDataHexStr3);+    strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);++    /* Digest must be 8 byte aligned */+    for(; i<56; i++)+    {+        strcat((char*)cesaDataAndMd5digest3, "00");+        strcat((char*)cesaDataAndSha1digest3, "00");+    }+    strcat((char*)cesaDataAndMd5digest3,  cesaHmacMd5digestHex3);+    strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);++#ifndef MV_NETBSD+    MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);+    MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);+#endif++#ifdef MV_VXWORKS+    {+        MV_STATUS       status;++        status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);+        if (status != OK)+        {+            mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",+                        INT_LVL_CESA, status);+            /* !!!! Dima cesaTestCleanup();*/+            return;+        }+        cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);+        if(cesaSemId == NULL)+        {+            mvOsPrintf("cesaTestStart: Can't create semaphore\n");+            return;+        }+        intEnable(INT_LVL_CESA);+    }+#endif /* MV_VXWORKS */++#if !defined(MV_NETBSD) && defined(__KERNEL__)+        if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) ) +        {+            mvOsPrintf( "cannot assign irq\n" );+            /* !!!! Dima cesaTestCleanup();*/+            return;+        }+        spin_lock_init( &cesaLock );+#endif+}++MV_STATUS   testRun(int idx, int caseIdx, int iter,+                    int reqSize, int checkMode)+{+    int                     testIdx, count, sid, digestSize;+    int                     blockSize;+    MV_CESA_TEST_SESSION*   pTestSession;+    MV_CESA_COMMAND         cmd;+    MV_STATUS               status;++    memset(&cmd, 0, sizeof(cmd));++    pTestSession = getTestSessionDb(idx, &testIdx);+    if(pTestSession == NULL)+    {+        mvOsPrintf("Test %d is not exist\n", idx);+        return MV_BAD_PARAM;+    }+    pTestSession = &pTestSession[testIdx];++    sid = pTestSession->sid;+    if(sid == -1)+    {+        mvOsPrintf("Test %d is not opened\n", idx);+        return MV_BAD_STATE;+    }+    switch(pTestSession->cryptoAlgorithm)+    {+        case MV_CESA_CRYPTO_DES:+        case MV_CESA_CRYPTO_3DES:+            blockSize = MV_CESA_DES_BLOCK_SIZE;+            break;++        case MV_CESA_CRYPTO_AES:+            blockSize = MV_CESA_AES_BLOCK_SIZE;+            break;++        case MV_CESA_CRYPTO_NULL:+            blockSize = 0;+            break;++        default:+            mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",+                pTestSession->cryptoAlgorithm);+        return MV_BAD_PARAM;+    }+    switch(pTestSession->macAlgorithm)+    {+        case MV_CESA_MAC_MD5:+        case MV_CESA_MAC_HMAC_MD5:+            digestSize = MV_CESA_MD5_DIGEST_SIZE;+            break;++        case MV_CESA_MAC_SHA1:+        case MV_CESA_MAC_HMAC_SHA1:+            digestSize = MV_CESA_SHA1_DIGEST_SIZE;+            break;+        default:+            digestSize = 0;+    }++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    if(pTestSession->direction == MV_CESA_DIR_ENCODE)+    {+        cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;+        cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;+    }+    else+    {+        cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;+        cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;+    }++    cmd.sessionId = sid;+    if(checkMode == CESA_FAST_CHECK_MODE)+    {+        cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;+        cmd.macLength = cesaTestCases[caseIdx].macLength;+    }+    else+    {+        cmd.cryptoLength = reqSize;+        cmd.macLength = reqSize;+    }+    cesaRateSize = cmd.cryptoLength;+    cesaReqSize = cmd.cryptoLength;+    cmd.cryptoOffset = 0;+    if(pTestSession->operation != MV_CESA_MAC_ONLY)+    {+        if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||+            (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )+        {+            cmd.ivOffset = 0;+            cmd.cryptoOffset = blockSize;+            if(cesaTestCases[caseIdx].pCryptoIV == NULL)+            {+                cmd.ivFromUser = 1;+            }+            else+            {+                cmd.ivFromUser = 0;+                mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);+            }+            cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;+        }+    }++/*+    mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",+                cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);+*/+    if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)+    {+        cmd.macOffset = cmd.cryptoOffset;++        if(cesaTestCases[caseIdx].digestOffset == -1)+        {+            cmd.digestOffset = cmd.macOffset + cmd.macLength;+            cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);+        }+        else+        {+            cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;+        }+        if( (cmd.digestOffset + digestSize) > cesaReqSize)+            cesaReqSize = cmd.digestOffset + digestSize;+    }++    cesaCheckMode = checkMode;++    if(checkMode == CESA_NULL_CHECK_MODE)+    {+        cesaCheckSize = 0;+        cesaCheckOffset = 0;+    }+    else+    {+        if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)+        {+            cesaCheckOffset = 0;+            cesaCheckSize = cmd.cryptoLength;+        }+        else+        {+            cesaCheckSize = digestSize;+            cesaCheckOffset = cmd.digestOffset;+        }+    }+/*+    mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",+                cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);++    mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",+                blockSize, cmd.ivOffset, cmd.ivFromUser,+                cmd.cryptoOffset, cmd.cryptoLength);++    mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",+                cmd.macOffset, cmd.digestOffset, cmd.macLength);+*/+    status = testCmd(sid, iter, &cmd, pTestSession,+                     cesaTestCases[caseIdx].pCryptoIV, blockSize);++    if(status != MV_OK)+        return status;++    /* Wait when all callbacks is received */+    count = 0;+    while(cesaIsReady == MV_FALSE)+    {+        mvOsSleep(10);+        count++;+        if(count > 100)+        {+            mvOsPrintf("testRun: Timeout occured\n");+            return MV_TIMEOUT;+        }+    }++    return MV_OK;+}+++void cesaTestStop(void)+{+    MV_CESA_MBUF    *pMbufSrc, *pMbufDst;+    MV_BUF_INFO     *pFragsSrc, *pFragsDst;+    int             i;++    /* Release all allocated memories */+    pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);+    pFragsSrc = cesaCmdRing[0].pSrc->pFrags;++    pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);+    pFragsDst = cesaCmdRing[0].pDst->pFrags;++    mvOsFree(pMbufSrc);+    mvOsFree(pMbufDst);+    mvOsFree(pFragsSrc);+    mvOsFree(pFragsDst);++    for(i=0; i<CESA_DEF_REQ_SIZE; i++)+    {+        mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,+			 cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,+			 cesaReqBufs[i].memHandle);+    }+    cesaDataHexStr3[0] = '\0';+}++void    desTest(int iter, int reqSize, int checkMode)+{+    int         mode, i;+    MV_STATUS   status;++    mode = checkMode;+    if(checkMode == CESA_FULL_CHECK_MODE)+        mode = CESA_FAST_CHECK_MODE;+    i = iter;+    if(mode != CESA_NULL_CHECK_MODE)+        i = 1;++    testOpen(0);+    testOpen(1);+    testOpen(2);+    testOpen(3);++/* DES / ECB mode / Encrypt only */+    status = testRun(0, 1, iter, reqSize, checkMode);+    printTestResults(0, status, checkMode);++/* DES / ECB mode / Decrypt only */+    status = testRun(1, 1, iter, reqSize, checkMode);+    printTestResults(1, status, checkMode);++/* DES / CBC mode / Encrypt only */+    status = testRun(2, 2, i, reqSize, mode);+    printTestResults(2, status, mode);++/* DES / CBC mode / Decrypt only */+    status = testRun(3, 2, iter, reqSize, mode);+    printTestResults(3, status, mode);++    testClose(0);+    testClose(1);+    testClose(2);+    testClose(3);+}++void    tripleDesTest(int iter, int reqSize, int checkMode)+{+    int         mode, i;+    MV_STATUS   status;++    mode = checkMode;+    if(checkMode == CESA_FULL_CHECK_MODE)+        mode = CESA_FAST_CHECK_MODE;+    i = iter;+    if(mode != CESA_NULL_CHECK_MODE)+        i = 1;++    testOpen(100);+    testOpen(101);+    testOpen(102);+    testOpen(103);++/* 3DES / ECB mode / Encrypt only */+    status = testRun(100, 1, iter, reqSize, checkMode);+    printTestResults(100, status, checkMode);++/* 3DES / ECB mode / Decrypt only */+    status = testRun(101, 1, iter, reqSize, checkMode);+    printTestResults(101, status, checkMode);++/* 3DES / CBC mode / Encrypt only */+    status = testRun(102, 2, i, reqSize, mode);+    printTestResults(102, status, mode);++/* 3DES / CBC mode / Decrypt only */+    status = testRun(103, 2, iter, reqSize, mode);+    printTestResults(103, status, mode);++    testClose(100);+    testClose(101);+    testClose(102);+    testClose(103);+}++void    aesTest(int iter, int reqSize, int checkMode)+{+    MV_STATUS   status;+    int         mode, i;++    mode = checkMode;+    if(checkMode == CESA_FULL_CHECK_MODE)+        mode = CESA_FAST_CHECK_MODE;++    i = iter;+    if(mode != CESA_NULL_CHECK_MODE)+        i = 1;++    testOpen(200);+    testOpen(201);+    testOpen(202);+    testOpen(203);+    testOpen(204);+    testOpen(205);+    testOpen(206);+    testOpen(207);+    testOpen(208);++/* AES-128 Encode ECB mode */+    status = testRun(200, 3, iter, reqSize, checkMode);+    printTestResults(200, status, checkMode);++/* AES-128 Decode ECB mode */+    status = testRun(201, 3, iter, reqSize, checkMode);+    printTestResults(201, status, checkMode);++/* AES-128 Encode CBC mode (IV from SA) */+    status = testRun(202, 10, i, reqSize, mode);+    printTestResults(202, status, mode);++/* AES-128 Encode CBC mode (IV from User) */+    status = testRun(202, 24, i, reqSize, mode);+    printTestResults(202, status, mode);++/* AES-128 Decode CBC mode */+    status = testRun(203, 24, iter, reqSize, mode);+    printTestResults(203, status, checkMode);++/* AES-192 Encode ECB mode */+    status = testRun(204, 4, iter, reqSize, checkMode);+    printTestResults(204, status, checkMode);++/* AES-192 Decode ECB mode */+    status = testRun(205, 4, iter, reqSize, checkMode);+    printTestResults(205, status, checkMode);++/* AES-256 Encode ECB mode */+    status = testRun(206, 5, iter, reqSize, checkMode);+    printTestResults(206, status, checkMode);++/* AES-256 Decode ECB mode */+    status = testRun(207, 5, iter, reqSize, checkMode);+    printTestResults(207, status, checkMode);++#if defined(MV_LINUX)+/* AES-128 Encode CTR mode */+    status = testRun(208, 23, iter, reqSize, mode);+    printTestResults(208, status, checkMode);+#endif+    testClose(200);+    testClose(201);+    testClose(202);+    testClose(203);+    testClose(204);+    testClose(205);+    testClose(206);+    testClose(207);+    testClose(208);+}+++void    mdTest(int iter, int reqSize, int checkMode)+{+    int         mode;+    MV_STATUS   status;++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    mode = checkMode;+    if(checkMode == CESA_FULL_CHECK_MODE)+        mode = CESA_FAST_CHECK_MODE;++    testOpen(300);+    testOpen(301);+    testOpen(302);+    testOpen(303);+    testOpen(305);++/* HMAC-MD5 Generate signature test */+    status = testRun(300, 6, iter, reqSize, mode);+    printTestResults(300, status, checkMode);++/* HMAC-MD5 Verify Signature test */+    status = testRun(301, 7, iter, reqSize, mode);+    printTestResults(301, status, checkMode);++/* HMAC-MD5 Generate signature test */+    status = testRun(302, 8, iter, reqSize, mode);+    printTestResults(302, status, checkMode);++/* HMAC-MD5 Verify Signature test */+    status = testRun(303, 9, iter, reqSize, mode);+    printTestResults(303, status, checkMode);++/* HASH-MD5 Generate signature test */+    status = testRun(305, 15, iter, reqSize, mode);+    printTestResults(305, status, checkMode);++    testClose(300);+    testClose(301);+    testClose(302);+    testClose(303);+    testClose(305);+}++void    shaTest(int iter, int reqSize, int checkMode)+{+    int         mode;+    MV_STATUS   status;++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    mode = checkMode;+    if(checkMode == CESA_FULL_CHECK_MODE)+        mode = CESA_FAST_CHECK_MODE;++    testOpen(400);+    testOpen(401);+    testOpen(402);+    testOpen(403);+    testOpen(405);++/* HMAC-SHA1 Generate signature test */+    status = testRun(400, 11, iter, reqSize, mode);+    printTestResults(400, status, checkMode);++/* HMAC-SHA1 Verify Signature test */+    status = testRun(401, 12, iter, reqSize, mode);+    printTestResults(401, status, checkMode);++/* HMAC-SHA1 Generate signature test */+    status = testRun(402, 13, iter, reqSize, mode);+    printTestResults(402, status, checkMode);++/* HMAC-SHA1 Verify Signature test */+    status = testRun(403, 14, iter, reqSize, mode);+    printTestResults(403, status, checkMode);++/* HMAC-SHA1 Generate signature test */+    status = testRun(405, 16, iter, reqSize, mode);+    printTestResults(405, status, checkMode);++    testClose(400);+    testClose(401);+    testClose(402);+    testClose(403);+    testClose(405);+}++void    combiTest(int iter, int reqSize, int checkMode)+{+    MV_STATUS   status;+    int         mode, i;++    mode = checkMode;+    if(checkMode == CESA_FULL_CHECK_MODE)+        mode = CESA_FAST_CHECK_MODE;++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    i = iter;+    if(mode != CESA_NULL_CHECK_MODE)+        i = 1;++    testOpen(500);+    testOpen(501);+    testOpen(502);+    testOpen(503);+    testOpen(504);+    testOpen(505);+    testOpen(506);+    testOpen(507);++/* DES ECB + MD5 encode test */+    status = testRun(500, 17, iter, reqSize, mode);+    printTestResults(500, status, mode);++/* DES ECB + SHA1 encode test */+    status = testRun(501, 18, iter, reqSize, mode);+    printTestResults(501, status, mode);++/* 3DES ECB + MD5 encode test */+    status = testRun(502, 17, iter, reqSize, mode);+    printTestResults(502, status, mode);++/* 3DES ECB + SHA1 encode test */+    status = testRun(503, 18, iter, reqSize, mode);+    printTestResults(503, status, mode);++/* 3DES CBC + MD5 encode test */+    status = testRun(504, 19, i, reqSize, mode);+    printTestResults(504, status, mode);++/* 3DES CBC + SHA1 encode test */+    status = testRun(505, 20, i, reqSize, mode);+    printTestResults(505, status, mode);++/* AES-128 CBC + MD5 encode test */+    status = testRun(506, 21, i, reqSize, mode);+    printTestResults(506, status, mode);++/* AES-128 CBC + SHA1 encode test */+    status = testRun(507, 22, i, reqSize, mode);+    printTestResults(507, status, mode);++    testClose(500);+    testClose(501);+    testClose(502);+    testClose(503);+    testClose(504);+    testClose(505);+    testClose(506);+    testClose(507);+}++void    cesaOneTest(int testIdx, int caseIdx,+                    int iter, int reqSize, int checkMode)+{+    MV_STATUS   status;++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",+                testIdx, caseIdx, reqSize, iter);++    status = testOpen(testIdx);++    status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);+    printTestResults(testIdx, status, checkMode);+    status = testClose(testIdx);++}++void    cesaTest(int iter, int reqSize, int checkMode)+{+    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    mvOsPrintf("%d iteration\n", iter);+    mvOsPrintf("%d size\n\n", reqSize);++/* DES tests */+    desTest(iter, reqSize, checkMode);++/* 3DES tests */+    tripleDesTest(iter, reqSize, checkMode);++/* AES tests */+    aesTest(iter, reqSize, checkMode);++/* MD5 tests */+    mdTest(iter, reqSize, checkMode);++/* SHA-1 tests */+    shaTest(iter, reqSize, checkMode);+}++void    multiSizeTest(int idx, int iter, int checkMode, char* inputData)+{+    MV_STATUS               status;+    int                     i;+    MV_CESA_SIZE_TEST*      pMultiTest;++    if( testOpen(idx) != MV_OK)+        return;++    if(iter == 0)+        iter = CESA_DEF_ITER_NUM;++    if(checkMode == CESA_SHOW_CHECK_MODE)+    {+        iter = 1;+    }+    else+        checkMode = CESA_FULL_CHECK_MODE;++    cesaTestCases[0].plainHexStr = inputData;+    cesaTestCases[0].pCryptoIV = NULL;++    switch(idx)+    {+        case 302:+            pMultiTest = mdMultiSizeTest302;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = cesaDataHexStr3;+            break;++        case 304:+            pMultiTest = mdMultiSizeTest304;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 305:+            pMultiTest = mdMultiSizeTest305;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 402:+            pMultiTest = shaMultiSizeTest402;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 404:+            pMultiTest = shaMultiSizeTest404;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 405:+            pMultiTest = shaMultiSizeTest405;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 502:+            pMultiTest = tripleDesMdMultiSizeTest502;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 503:+            pMultiTest = tripleDesShaMultiSizeTest503;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 504:+            iter = 1;+            pMultiTest = cbc3desMdMultiSizeTest504;+            cesaTestCases[0].pCryptoIV = iv1;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 505:+            iter = 1;+            pMultiTest = cbc3desShaMultiSizeTest505;+            cesaTestCases[0].pCryptoIV = iv1;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 506:+            iter = 1;+            pMultiTest = cbcAes128md5multiSizeTest506;+            cesaTestCases[0].pCryptoIV = iv5;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        case 507:+            iter = 1;+            pMultiTest = cbcAes128sha1multiSizeTest507;+            cesaTestCases[0].pCryptoIV = iv5;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+            break;++        default:+            iter = 1;+            checkMode = CESA_SHOW_CHECK_MODE;+            pMultiTest = mdMultiSizeTest302;+            if(inputData == NULL)+                cesaTestCases[0].plainHexStr = hashHexStr80;+    }+    i = 0;+    while(pMultiTest[i].outputHexStr != NULL)+    {+        cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;+        status = testRun(idx, 0, iter, pMultiTest[i].size,+                         checkMode);+        if(checkMode != CESA_SHOW_CHECK_MODE)+        {+            cesaReqSize = pMultiTest[i].size;+            printTestResults(idx, status, checkMode);+        }+        if(status != MV_OK)+            break;+        i++;+    }+    testClose(idx);+/*+    mvCesaDebugStatus();+    cesaTestPrintStatus();+*/+}++void    open_session_test(int idx, int caseIdx, int iter)+{+    int         reqIdError, cryptoError, openErrors, i;+    int         openErrDisp[100];+    MV_STATUS   status;++    memset(openErrDisp, 0, sizeof(openErrDisp));+    openErrors = 0;+    reqIdError = 0;+    cryptoError = 0;+    for(i=0; i<iter; i++)+    {+        status = testOpen(idx);+        if(status != MV_OK)+        {+            openErrors++;+            openErrDisp[status]++;+        }+        else+        {+            testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);+            if(cesaCryptoError > 0)+                cryptoError++;+            if(cesaReqIdError > 0)+                reqIdError++;++            testClose(idx);+        }+    }+    if(cryptoError > 0)+        mvOsPrintf("cryptoError : %d\n", cryptoError);+    if(reqIdError > 0)+        mvOsPrintf("reqIdError  : %d\n", reqIdError);++    if(openErrors > 0)+    {+        mvOsPrintf("Open Errors = %d\n", openErrors);+        for(i=0; i<100; i++)+        {+            if(openErrDisp[i] != 0)+                mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);+        }+    }+}+++void    loopback_test(int idx, int iter, int size, char* pPlainData)+{+}+++#if defined(MV_VXWORKS)+int testMode = 0;+unsigned __TASKCONV cesaTask(void* args)+{+    int reqSize = cesaReqSize;++    if(testMode == 0)+    {+        cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,+                    reqSize, cesaCheckMode);+    }+    else+    {+        if(testMode == 1)+        {+            cesaTest(cesaIteration, reqSize, cesaCheckMode);+            combiTest(cesaIteration, reqSize, cesaCheckMode);+        }+        else+        {+            multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);+        }+    }+    return 0;+}++void oneTest(int testIdx, int caseIdx,+              int iter, int reqSize, int checkMode)+{+    long    rc;++    cesaIteration = iter;+    cesaReqSize = cesaRateSize = reqSize;+    cesaCheckMode = checkMode;+    testMode = 0;+    cesaTestIdx = testIdx;+    cesaCaseIdx = caseIdx;+    rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);+    if (rc != MV_OK)+    {+        mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);+    }+}++void multiTest(int iter, int reqSize, int checkMode)+{+    long    rc;++    cesaIteration = iter;+    cesaCheckMode = checkMode;+    cesaReqSize = reqSize;+    testMode = 1;+    rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);+    if (rc != MV_OK)+    {+        mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);+    }+}++void sizeTest(int testIdx, int iter, int checkMode)+{+    long    rc;++    cesaIteration = iter;+        cesaCheckMode = checkMode;+        testMode = 2;+        cesaIdx = testIdx;+    rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);+    if (rc != MV_OK)+    {+        mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);+    }+}++#endif /* MV_VXWORKS */++extern void    mvCesaDebugSA(short sid, int mode);+void    cesaTestPrintSession(int idx)+{+    int                     testIdx;+    MV_CESA_TEST_SESSION*   pTestSession;++    pTestSession = getTestSessionDb(idx, &testIdx);+    if(pTestSession == NULL)+    {+        mvOsPrintf("Test %d is not exist\n", idx);+        return;+    }+    pTestSession = &pTestSession[testIdx];++    if(pTestSession->sid == -1)+    {+        mvOsPrintf("Test session %d is not opened\n", idx);+        return;+    }++    mvCesaDebugSA(pTestSession->sid, 1);+}++void    cesaTestPrintStatus(void)+{+    mvOsPrintf("\n\t Cesa Test Status\n\n");++    mvOsPrintf("isrCount=%d\n",+                cesaTestIsrCount);++#ifdef CESA_TEST_DEBUG+    {+        int i, j;+        j = cesaTestTraceIdx;+        mvOsPrintf("No  Type  Cause   rCause   iCause   Res     Time     pReady    pProc    pEmpty\n");+        for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)+        {+            mvOsPrintf("%02d.  %d   0x%04x  0x%04x   0x%04x   0x%02x   0x%02x   %02d   0x%06x  %p  %p  %p\n",+                j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,+                cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,+                cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);+            j++;+            if(j == MV_CESA_TEST_TRACE_SIZE)+                j = 0;+        }+    }+#endif /* CESA_TEST_DEBUG */+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.c	2010-11-09 20:28:05.822495424 +0100@@ -0,0 +1,158 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvOs.h"+#include "mvLru.h"+/* LRU Cache support */+++/* Init LRU cache database */+MV_LRU_CACHE*   mvLruCacheInit(int numOfEntries)+{+    int             i;+    MV_LRU_CACHE*   pLruCache;++    pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));+    if(pLruCache == NULL)+    {+        return NULL;+    }+    memset(pLruCache, 0, sizeof(MV_LRU_CACHE));++    pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));+    if(pLruCache->table == NULL)+    {+        mvOsFree(pLruCache);+        return NULL;+    }+    memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));+    pLruCache->tableSize = numOfEntries;++    for(i=0; i<numOfEntries; i++)+    {+        pLruCache->table[i].next = i+1;+        pLruCache->table[i].prev = i-1;         +    }+    pLruCache->least = 0;+    pLruCache->most = numOfEntries-1;   ++    return pLruCache;+}++void    mvLruCacheFinish(MV_LRU_CACHE* pLruCache)+{+    mvOsFree(pLruCache->table);+    mvOsFree(pLruCache);+}++/* Update LRU cache database after using cache Index */+void    mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)+{+    int prev, next;++    if(cacheIdx == pLruHndl->most)+        return;++    next = pLruHndl->table[cacheIdx].next;+    if(cacheIdx == pLruHndl->least)+    {+        pLruHndl->least = next;+    }+    else+    {+        prev = pLruHndl->table[cacheIdx].prev;++        pLruHndl->table[next].prev = prev;+        pLruHndl->table[prev].next = next;+    }++    pLruHndl->table[pLruHndl->most].next = cacheIdx;+    pLruHndl->table[cacheIdx].prev = pLruHndl->most;+    pLruHndl->most = cacheIdx;+}++/* Delete LRU cache entry */+void    mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)+{+    int prev, next;++    if(cacheIdx == pLruHndl->least)+        return;++    prev = pLruHndl->table[cacheIdx].prev;+    if(cacheIdx == pLruHndl->most)+    {+        pLruHndl->most = prev;+    }+    else+    {+        next = pLruHndl->table[cacheIdx].next;++        pLruHndl->table[next].prev = prev;+        pLruHndl->table[prev].next = next;+    }+    pLruHndl->table[pLruHndl->least].prev = cacheIdx;+    pLruHndl->table[cacheIdx].next = pLruHndl->least;+    pLruHndl->least = cacheIdx;+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvLru.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvLru.h	2010-11-09 20:28:05.861235773 +0100@@ -0,0 +1,112 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+/*******************************************************************************+* mvLru.h - Header File for Least Recently Used Cache algorithm+*+* DESCRIPTION:+*       This header file contains macros typedefs and function declaration for+*       the Least Recently Used Cache algorithm.+*+*******************************************************************************/++#ifndef __mvLru_h__+#define __mvLru_h__+++typedef struct+{+    int next;+    int prev;+} MV_LRU_ENTRY;++typedef struct+{+    int             least;+    int             most;+    MV_LRU_ENTRY*   table;+    int             tableSize;++}MV_LRU_CACHE;+++/* Find Cache index for replacement LRU */+static INLINE int     mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)+{+    return pLruHndl->least;+}++/* Init LRU cache module */+MV_LRU_CACHE*   mvLruCacheInit(int numOfEntries);++/* Finish LRU cache module */+void    mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);++/* Update LRU cache database after using cache Index */+void    mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);++/* Delete LRU cache entry */+void    mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);+++#endif /* __mvLru_h__ */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.c	2010-11-09 20:28:05.902495799 +0100@@ -0,0 +1,349 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvOs.h"+#include "mvMD5.h"++static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);+ +#ifdef  MV_CPU_LE+#define mvByteReverse(buf, len)   /* Nothing */+#else+static void mvByteReverse(unsigned char *buf, unsigned longs);++/*+ * Note: this code is harmless on little-endian machines.+ */+static void mvByteReverse(unsigned char *buf, unsigned longs)+{+    MV_U32 t;++    do +    {+        t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |+                      ((unsigned) buf[1] << 8 | buf[0]);+        *(MV_U32 *) buf = t;+        buf += 4;+    } while (--longs);+}+#endif++/*+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious+ * initialization constants.+ */+void    mvMD5Init(MV_MD5_CONTEXT *ctx)+{+    ctx->buf[0] = 0x67452301;+    ctx->buf[1] = 0xefcdab89;+    ctx->buf[2] = 0x98badcfe;+    ctx->buf[3] = 0x10325476;++    ctx->bits[0] = 0;+    ctx->bits[1] = 0;+}++/*+ * Update context to reflect the concatenation of another buffer full+ * of bytes.+ */+void    mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)+{+    MV_U32 t;++    /* Update bitcount */++    t = ctx->bits[0];+    if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)+        ctx->bits[1]++;         /* Carry from low to high */+    ctx->bits[1] += len >> 29;++    t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */++    /* Handle any leading odd-sized chunks */++    if (t) +    {+        unsigned char *p = (unsigned char *) ctx->in + t;++        t = 64 - t;+        if (len < t) +        {+            memcpy(p, buf, len);+            return;+        }+        memcpy(p, buf, t);+        mvByteReverse(ctx->in, MV_MD5_MAC_LEN);+        mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);+        buf += t;+        len -= t;+    }+    /* Process data in 64-byte chunks */++    while (len >= 64) +    {+        memcpy(ctx->in, buf, 64);+        mvByteReverse(ctx->in, MV_MD5_MAC_LEN);+        mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);+        buf += 64;+        len -= 64;+    }++    /* Handle any remaining bytes of data. */++    memcpy(ctx->in, buf, len);+}++/*+ * Final wrapup - pad to 64-byte boundary with the bit pattern+ * 1 0* (64-bit count of bits processed, MSB-first)+ */+void    mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)+{+    unsigned count;+    unsigned char *p;++    /* Compute number of bytes mod 64 */+    count = (ctx->bits[0] >> 3) & 0x3F;++    /* Set the first char of padding to 0x80.  This is safe since there is+       always at least one byte free */+    p = ctx->in + count;+    *p++ = 0x80;++    /* Bytes of padding needed to make 64 bytes */+    count = 64 - 1 - count;++    /* Pad out to 56 mod 64 */+    if (count < 8) +    {+        /* Two lots of padding:  Pad the first block to 64 bytes */+        memset(p, 0, count);+        mvByteReverse(ctx->in, MV_MD5_MAC_LEN);+        mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);++        /* Now fill the next block with 56 bytes */+        memset(ctx->in, 0, 56);+    } +    else +    {+        /* Pad block to 56 bytes */+        memset(p, 0, count - 8);+    }+    mvByteReverse(ctx->in, 14);++    /* Append length in bits and transform */+    ((MV_U32 *) ctx->in)[14] = ctx->bits[0];+    ((MV_U32 *) ctx->in)[15] = ctx->bits[1];++    mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);+    mvByteReverse((unsigned char *) ctx->buf, 4);+    memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);+    memset(ctx, 0, sizeof(ctx));        /* In case it's sensitive */+}++/* The four core functions - F1 is optimized somewhat */++/* #define F1(x, y, z) (x & y | ~x & z) */+#define F1(x, y, z) (z ^ (x & (y ^ z)))+#define F2(x, y, z) F1(z, x, y)+#define F3(x, y, z) (x ^ y ^ z)+#define F4(x, y, z) (y ^ (x | ~z))++/* This is the central step in the MD5 algorithm. */+#define MD5STEP(f, w, x, y, z, data, s) \+        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )++/*+ * The core of the MD5 algorithm, this alters an existing MD5 hash to+ * reflect the addition of 16 longwords of new data.  MD5Update blocks+ * the data and converts bytes into longwords for this routine.+ */+static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])+{+    register MV_U32 a, b, c, d;++    a = buf[0];+    b = buf[1];+    c = buf[2];+    d = buf[3];++    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);+    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);+    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);+    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);+    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);+    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);+    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);+    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);+    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);+    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);+    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);+    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);+    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);+    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);+    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);+    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);++    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);+    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);+    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);+    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);+    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);+    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);+    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);+    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);+    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);+    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);+    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);+    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);+    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);+    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);+    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);+    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);++    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);+    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);+    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);+    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);+    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);+    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);+    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);+    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);+    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);+    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);+    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);+    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);+    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);+    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);+    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);+    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);++    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);+    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);+    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);+    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);+    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);+    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);+    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);+    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);+    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);+    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);+    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);+    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);+    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);+    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);+    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);+    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);++    buf[0] += a;+    buf[1] += b;+    buf[2] += c;+    buf[3] += d;+}++void    mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)+{+    MV_MD5_CONTEXT  ctx;++    mvMD5Init(&ctx);+    mvMD5Update(&ctx, buf, len);+    mvMD5Final(digest, &ctx);+}+++void    mvHmacMd5(unsigned char const* text, int text_len,+                  unsigned char const* key, int key_len,+                  unsigned char* digest)+{+    int             i;+    MV_MD5_CONTEXT  ctx;+    unsigned char   k_ipad[64+1]; /* inner padding - key XORd with ipad */+    unsigned char   k_opad[64+1]; /* outer padding - key XORd with opad */++    /* start out by storing key in pads */+    memset(k_ipad, 0, 64);+    memcpy(k_ipad, key, key_len);+    memset(k_opad, 0, 64);+    memcpy(k_opad, key, key_len);++    /* XOR key with ipad and opad values */+    for (i=0; i<64; i++) +    {+	    k_ipad[i] ^= 0x36;+	    k_opad[i] ^= 0x5c;+    }++    /* perform inner MD5 */+    mvMD5Init(&ctx);                   /* init ctx for 1st pass */+    mvMD5Update(&ctx, k_ipad, 64);    /* start with inner pad */+    mvMD5Update(&ctx, text, text_len); /* then text of datagram */+    mvMD5Final(digest, &ctx);          /* finish up 1st pass */++    /* perform outer MD5 */+    mvMD5Init(&ctx);                   /* init ctx for 2nd pass */+    mvMD5Update(&ctx, k_opad, 64);     /* start with outer pad */+    mvMD5Update(&ctx, digest, 16);     /* then results of 1st hash */+    mvMD5Final(digest, &ctx);          /* finish up 2nd pass */+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvMD5.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvMD5.h	2010-11-09 20:28:05.942495390 +0100@@ -0,0 +1,93 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __mvMD5_h__+#define __mvMD5_h__++#include "mvMD5.h"++#define MV_MD5_MAC_LEN 16+ + +typedef struct +{+    MV_U32 buf[4];+    MV_U32 bits[2];+    MV_U8  in[64];++} MV_MD5_CONTEXT;+ +void mvMD5Init(MV_MD5_CONTEXT *context);+void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,+                unsigned len);+void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);++void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);++void mvHmacMd5(unsigned char const* text, int text_len,+                  unsigned char const* key, int key_len,+                  unsigned char* digest);+  ++#endif /* __mvMD5_h__ */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.c	2010-11-09 20:28:05.972495400 +0100@@ -0,0 +1,239 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvOs.h"+#include "mvSHA1.h"++#define SHA1HANDSOFF  ++typedef union +{+    MV_U8   c[64];+    MV_U32  l[16];++} CHAR64LONG16;++static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer); ++#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))++ +#ifdef MV_CPU_LE+#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \+        (rol(block->l[i], 8) & 0x00FF00FF))+#else+#define blk0(i) block->l[i]+#endif+#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \+        block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))++/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */+#define R0(v,w,x,y,z,i) \+        z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \+        w = rol(w, 30);+#define R1(v,w,x,y,z,i) \+        z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \+        w = rol(w, 30);+#define R2(v,w,x,y,z,i) \+        z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);+#define R3(v,w,x,y,z,i) \+        z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \+        w = rol(w, 30);+#define R4(v,w,x,y,z,i) \+        z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \+        w=rol(w, 30);++/* Hash a single 512-bit block. This is the core of the algorithm. */+static void    mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)+{+    MV_U32          a, b, c, d, e;+    CHAR64LONG16*   block;++#ifdef SHA1HANDSOFF+    static MV_U32  workspace[16];++    block = (CHAR64LONG16 *) workspace;+    memcpy(block, buffer, 64);+#else+    block = (CHAR64LONG16 *) buffer;+#endif+    /* Copy context->state[] to working vars */+    a = state[0];+    b = state[1];+    c = state[2];+    d = state[3];+    e = state[4];+    /* 4 rounds of 20 operations each. Loop unrolled. */+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);+    /* Add the working vars back into context.state[] */+    state[0] += a;+    state[1] += b;+    state[2] += c;+    state[3] += d;+    state[4] += e;+    /* Wipe variables */+    a = b = c = d = e = 0;+}++void    mvSHA1Init(MV_SHA1_CTX* context)+{+    /* SHA1 initialization constants */+    context->state[0] = 0x67452301;+    context->state[1] = 0xEFCDAB89;+    context->state[2] = 0x98BADCFE;+    context->state[3] = 0x10325476;+    context->state[4] = 0xC3D2E1F0;+    context->count[0] = context->count[1] = 0;+}+++/* Run your data through this. */+void    mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data, +                     unsigned int len)+{+    MV_U32 i, j;++    j = (context->count[0] >> 3) & 63;+    if ((context->count[0] += len << 3) < (len << 3))+            context->count[1]++;+    context->count[1] += (len >> 29);+    if ((j + len) > 63) +    {+        memcpy(&context->buffer[j], data, (i = 64-j));+        mvSHA1Transform(context->state, context->buffer);+        for ( ; i + 63 < len; i += 64) +        {+            mvSHA1Transform(context->state, &data[i]);+        }+        j = 0;+    }+    else+    {+        i = 0;+    }+    memcpy(&context->buffer[j], &data[i], len - i);+}++void    mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)+{+    MV_U32  i;+    MV_U8   finalcount[8];++    for (i = 0; i < 8; i++) +    {+        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>+                      ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */+    }+    mvSHA1Update(context, (const unsigned char *) "\200", 1);+    while ((context->count[0] & 504) != 448) +    {+        mvSHA1Update(context, (const unsigned char *) "\0", 1);+    }+    mvSHA1Update(context, finalcount, 8);  /* Should cause a mvSHA1Transform()+                                          */+    for (i = 0; i < 20; i++) +    {+        digest[i] = (unsigned char)+                    ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);+    }+    /* Wipe variables */+    i = 0;+    memset(context->buffer, 0, 64);+    memset(context->state, 0, 20);+    memset(context->count, 0, 8);+    memset(finalcount, 0, 8);++#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */+    mvSHA1Transform(context->state, context->buffer);+#endif +}+++void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)+{+    MV_SHA1_CTX  ctx;++    mvSHA1Init(&ctx);+    mvSHA1Update(&ctx, buf, len);+    mvSHA1Final(digest, &ctx);+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa/mvSHA1.h	2010-11-09 20:28:06.012495345 +0100@@ -0,0 +1,88 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __mvSHA1_h__+#define __mvSHA1_h__++#include "mvSHA1.h"++#define MV_SHA1_MAC_LEN 20+ + +typedef struct +{+    MV_U32 state[5];+    MV_U32 count[2];+    MV_U8  buffer[64];++} MV_SHA1_CTX; + +void mvSHA1Init(MV_SHA1_CTX *context);+void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);+void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);++void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);+  ++#endif /* __mvSHA1_h__ */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c linux-2.6.36/crypto/ocf/kirkwood/cesa_ocf_drv.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/cesa_ocf_drv.c	2010-11-09 20:28:06.052495403 +0100@@ -0,0 +1,1296 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.+++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+*******************************************************************************/++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/sched.h>+#include <linux/wait.h>+#include <linux/crypto.h>+#include <linux/mm.h>+#include <linux/skbuff.h>+#include <linux/random.h>+#include <linux/platform_device.h>+#include <asm/scatterlist.h>+#include <linux/spinlock.h>+#include "ctrlEnv/sys/mvSysCesa.h"+#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */+#include <cryptodev.h>+#include <uio.h>+#include <plat/mv_cesa.h>+#include <linux/mbus.h>+#include "mvDebug.h"++#include "cesa/mvMD5.h"+#include "cesa/mvSHA1.h"++#include "cesa/mvCesaRegs.h"+#include "cesa/AES/mvAes.h"+#include "cesa/mvLru.h"++#undef  RT_DEBUG+#ifdef RT_DEBUG+static int debug = 1;+module_param(debug, int, 1);+MODULE_PARM_DESC(debug, "Enable debug");+#undef dprintk+#define dprintk(a...)	if (debug) { printk(a); } else+#else+static int debug = 0;+#undef dprintk+#define dprintk(a...)+#endif+++/* TDMA Regs */+#define WINDOW_BASE(i) 0xA00 + (i << 3)+#define WINDOW_CTRL(i) 0xA04 + (i << 3)++/* interrupt handling */+#undef CESA_OCF_POLLING+#undef CESA_OCF_TASKLET++#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)+#error "don't use both tasklet and polling mode"+#endif++extern int cesaReqResources;+/* support for spliting action into 2 actions */+#define CESA_OCF_SPLIT++/* general defines */+#define CESA_OCF_MAX_SES 128+#define CESA_Q_SIZE	 64+++/* data structures */+struct cesa_ocf_data {+        int                                      cipher_alg;+        int                                      auth_alg;+	int					 encrypt_tn_auth;+#define  auth_tn_decrypt  encrypt_tn_auth+	int					 ivlen;+	int 					 digestlen;+	short					 sid_encrypt;+	short					 sid_decrypt;+	/* fragment workaround sessions */+	short					 frag_wa_encrypt;+	short					 frag_wa_decrypt;+	short					 frag_wa_auth;+};++/* CESA device data */+struct cesa_dev {+	void __iomem *sram;+	void __iomem *reg;+        struct mv_cesa_platform_data *plat_data;+	int irq;+};++#define DIGEST_BUF_SIZE	32+struct cesa_ocf_process {+	MV_CESA_COMMAND 			cesa_cmd;+	MV_CESA_MBUF 				cesa_mbuf;	+	MV_BUF_INFO  				cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];+	char					digest[DIGEST_BUF_SIZE];+	int					digest_len;+	struct cryptop 				*crp;+	int 					need_cb;+};++/* global variables */+static int32_t			cesa_ocf_id 		= -1;+static struct cesa_ocf_data 	*cesa_ocf_sessions[CESA_OCF_MAX_SES];+static spinlock_t 		cesa_lock;+static struct cesa_dev cesa_device;++/* static APIs */+static int 		cesa_ocf_process	(device_t, struct cryptop *, int);+static int 		cesa_ocf_newsession	(device_t, u_int32_t *, struct cryptoini *);+static int 		cesa_ocf_freesession	(device_t, u_int64_t);+static void 		cesa_callback		(unsigned long);+static irqreturn_t	cesa_interrupt_handler	(int, void *);+#ifdef CESA_OCF_POLLING+static void cesa_interrupt_polling(void);+#endif+#ifdef CESA_OCF_TASKLET+static struct tasklet_struct cesa_ocf_tasklet;+#endif++static struct timeval          tt_start;+static struct timeval          tt_end;++/*+ * dummy device structure+ */++static struct {+	softc_device_decl	sc_dev;+} mv_cesa_dev;++static device_method_t mv_cesa_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	cesa_ocf_newsession),+	DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),+	DEVMETHOD(cryptodev_process,	cesa_ocf_process),+	DEVMETHOD(cryptodev_kprocess,	NULL),+};++++/* Add debug Trace */+#undef CESA_OCF_TRACE_DEBUG+#ifdef CESA_OCF_TRACE_DEBUG++#define MV_CESA_USE_TIMER_ID    0++typedef struct+{+    int             type;       /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */+    MV_U32          timeStamp;+    MV_U32          cause;+    MV_U32          realCause;+    MV_U32          dmaCause;+    int             resources;+    MV_CESA_REQ*    pReqReady;+    MV_CESA_REQ*    pReqEmpty;+    MV_CESA_REQ*    pReqProcess;+} MV_CESA_TEST_TRACE;++#define MV_CESA_TEST_TRACE_SIZE      50++static int cesaTestTraceIdx = 0;+static MV_CESA_TEST_TRACE    cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];++static void cesaTestTraceAdd(int type)+{+    cesaTestTrace[cesaTestTraceIdx].type = type;+    cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);+    //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);+    cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;+    cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;+    cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;+    cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;+    cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);+    cesaTestTraceIdx++;+    if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)+        cesaTestTraceIdx = 0;+}++#else /* CESA_OCF_TRACE_DEBUG */++#define cesaTestTraceAdd(x)++#endif /* CESA_OCF_TRACE_DEBUG */++unsigned int+get_usec(unsigned int start)+{+	if(start) {+		do_gettimeofday (&tt_start);+		return 0;+	}+	else {+        	do_gettimeofday (&tt_end);+        	tt_end.tv_sec -= tt_start.tv_sec;+        	tt_end.tv_usec -= tt_start.tv_usec;+        	if (tt_end.tv_usec < 0) {+                	tt_end.tv_usec += 1000 * 1000;+                	tt_end.tv_sec -= 1;+        	}+	}+	printk("time taken is  %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));+	return (tt_end.tv_usec + tt_end.tv_sec * 1000000);+}++#ifdef RT_DEBUG+/* + * check that the crp action match the current session+ */+static int +ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {+	int count = 0;+	int encrypt = 0, decrypt = 0, auth = 0;+	struct cryptodesc *crd;++        /* Go through crypto descriptors, processing as we go */+        for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {+		if(count > 2) {+			printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);+			return 1;+		}+		+		/* Encryption /Decryption */+		if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {+			/* check that the action is compatible with session */+			if(encrypt || decrypt) {+				printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);+				return 1;+			}++			if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */+				if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {+					printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);+					return 1;+				}+				encrypt++;+			}+			else { 					/* decrypt */+				if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {+					printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);+					return 1;+				}+				decrypt++;+			}++		}+		/* Authentication */+		else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {+			/* check that the action is compatible with session */+			if(auth) {+				printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);+				return 1;+			}+			if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {+				printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);+				return 1;+			}+			if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {+				printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);+				return 1;+			}+			auth++;+		} +		else {+			printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);+			return 1;+		}+	}+	return 0;++}+#endif++/*+ * Process a request.+ */+static int +cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)+{+	struct cesa_ocf_process *cesa_ocf_cmd = NULL;+	struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;+	MV_CESA_COMMAND	*cesa_cmd;+	struct cryptodesc *crd;+	struct cesa_ocf_data *cesa_ocf_cur_ses;+	int sid = 0, temp_len = 0, i;+	int encrypt = 0, decrypt = 0, auth = 0;+	int  status;+	struct sk_buff *skb = NULL;+	struct uio *uiop = NULL;+	unsigned char *ivp;+	MV_BUF_INFO *p_buf_info;	+	MV_CESA_MBUF *p_mbuf_info;+	unsigned long flags;++        dprintk("%s()\n", __FUNCTION__);++	if( cesaReqResources <= 1 ) {+                dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);+                return ERESTART;+	}++#ifdef RT_DEBUG+        /* Sanity check */+        if (crp == NULL) {+                printk("%s,%d: EINVAL\n", __FILE__, __LINE__);+                return EINVAL;+        }++        if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {+                printk("%s,%d: EINVAL\n", __FILE__, __LINE__);+                crp->crp_etype = EINVAL;+                return EINVAL;+        }++        sid = crp->crp_sid & 0xffffffff;+        if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {+                crp->crp_etype = ENOENT;+                printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);+                return EINVAL;+        }+#endif++	sid = crp->crp_sid & 0xffffffff;+	crp->crp_etype = 0;+	cesa_ocf_cur_ses = cesa_ocf_sessions[sid];++#ifdef RT_DEBUG+	if(ocf_check_action(crp, cesa_ocf_cur_ses)){+		goto p_error;+	}+#endif++	/* malloc a new  cesa process */	+	cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);+	+        if (cesa_ocf_cmd == NULL) {+            	printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);+            	goto p_error;+      	}+	memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));++	/* init cesa_process */+	cesa_ocf_cmd->crp = crp;+	/* always call callback */+	cesa_ocf_cmd->need_cb = 1;++	/* init cesa_cmd for usage of the HALs */+	cesa_cmd = &cesa_ocf_cmd->cesa_cmd;+	cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;+	cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */++	/* prepare src buffer 	*/+	/* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth.  */+	/* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */+	/* from skip to crd_len. 								  */+	p_buf_info = cesa_ocf_cmd->cesa_bufs;	+	p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;++	p_buf_info += 2; /* save 2 first buffers for IV and digest - +			    we won't append them to the end since, they +			    might be places in an unaligned addresses. */+	+	p_mbuf_info->pFrags = p_buf_info;+	temp_len = 0;++	/* handle SKB */+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		+		dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);+		skb = (struct sk_buff *) crp->crp_buf;++                if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {+                        printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);+                        goto p_error;+                }++		p_mbuf_info->mbufSize = skb->len;+		temp_len = skb->len;+        	/* first skb fragment */+        	p_buf_info->bufSize = skb_headlen(skb);+        	p_buf_info->bufVirtPtr = skb->data;+		p_buf_info++;++        	/* now handle all other skb fragments */+        	for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {+            		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];+            		p_buf_info->bufSize = frag->size;+            		p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;+            		p_buf_info++;+        	}+        	p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;+	}+	/* handle UIO */+	else if(crp->crp_flags & CRYPTO_F_IOV) {+	+		dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);+		uiop = (struct uio *) crp->crp_buf;++                if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {+                        printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);+                        goto p_error;+                }++		p_mbuf_info->mbufSize = crp->crp_ilen;+		p_mbuf_info->numFrags = uiop->uio_iovcnt;+		for(i = 0; i < uiop->uio_iovcnt; i++) {+			p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;+			p_buf_info->bufSize = uiop->uio_iov[i].iov_len;+			temp_len += p_buf_info->bufSize;+			dprintk("%s,%d: buf %x-> addr %x, size %x \n"+				, __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);+			p_buf_info++;			+		}++	}+	/* handle CONTIG */+	else {+		dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__); +		p_mbuf_info->numFrags = 1;+		p_mbuf_info->mbufSize = crp->crp_ilen;+		p_buf_info->bufVirtPtr = crp->crp_buf;+		p_buf_info->bufSize = crp->crp_ilen;+		temp_len = crp->crp_ilen;+		p_buf_info++;+	}+	+	/* Support up to 64K why? cause! */+	if(crp->crp_ilen > 64*1024) {+		printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);+		goto p_error;+	}++	if( temp_len != crp->crp_ilen ) {+		printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);+	}	++	cesa_cmd->pSrc = p_mbuf_info;+	cesa_cmd->pDst = p_mbuf_info;+	+	/* restore p_buf_info to point to first available buf */+	p_buf_info = cesa_ocf_cmd->cesa_bufs;	+	p_buf_info += 1; +++        /* Go through crypto descriptors, processing as we go */+        for (crd = crp->crp_desc; crd; crd = crd->crd_next) {+		+		/* Encryption /Decryption */+		if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {++			dprintk("%s,%d: cipher", __FILE__, __LINE__);++			cesa_cmd->cryptoOffset = crd->crd_skip;+    	              	cesa_cmd->cryptoLength = crd->crd_len;++			if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */+				dprintk(" encrypt \n");+				encrypt++;++				/* handle IV */+				if (crd->crd_flags & CRD_F_IV_EXPLICIT) {  /* IV from USER */+					dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);+					cesa_cmd->ivFromUser = 1;+					ivp = crd->crd_iv;++                                	/*+                                 	 * do we have to copy the IV back to the buffer ?+                                 	 */+                                	if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {+						dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);+						cesa_cmd->ivOffset = crd->crd_inject;+						crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);+                                	}+					else {+						dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);+						p_mbuf_info->numFrags++;+						p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen; +						p_mbuf_info->pFrags = p_buf_info;++						p_buf_info->bufVirtPtr = ivp;+						p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen; +						p_buf_info--;++						/* offsets */+						cesa_cmd->ivOffset = 0;+						cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;+						if(auth) {+							cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;+							cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen; +						}	+					}+                                }+				else {					/* random IV */+					dprintk("%s,%d: random IV \n", __FILE__, __LINE__);+					cesa_cmd->ivFromUser = 0;++                                	/*+                                 	 * do we have to copy the IV back to the buffer ?+                                 	 */+					/* in this mode the HAL will always copy the IV */+					/* given by the session to the ivOffset  	*/+					if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {+						cesa_cmd->ivOffset = crd->crd_inject;+					} +					else {+						/* if IV isn't copy, then how will the user know which IV did we use??? */+						printk("%s,%d: EINVAL\n", __FILE__, __LINE__);+						goto p_error; +					}+				}+			}+			else { 					/* decrypt */+				dprintk(" decrypt \n");+				decrypt++;+				cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;++				/* handle IV */+				if (crd->crd_flags & CRD_F_IV_EXPLICIT) {+					dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);+					/* append the IV buf to the mbuf */+					cesa_cmd->ivFromUser = 1;	+					p_mbuf_info->numFrags++;+					p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen; +					p_mbuf_info->pFrags = p_buf_info;++					p_buf_info->bufVirtPtr = crd->crd_iv;+					p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen; +					p_buf_info--;++					/* offsets */+					cesa_cmd->ivOffset = 0;+					cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;+					if(auth) {+						cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;+						cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen; +					}+                                }+				else {+					dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);+					cesa_cmd->ivFromUser = 0;+					cesa_cmd->ivOffset = crd->crd_inject;+				}+			}++		}+		/* Authentication */+		else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {+			dprintk("%s,%d:  Authentication \n", __FILE__, __LINE__);+			auth++;+			cesa_cmd->macOffset = crd->crd_skip;+			cesa_cmd->macLength = crd->crd_len;++			/* digest + mac */+			cesa_cmd->digestOffset = crd->crd_inject;+		} +		else {+			printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);+			goto p_error;+		}+	}++	dprintk("\n");+	dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);+	dprintk("%s,%d: IV from user: %d. IV offset %x \n",  __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);+	dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);+	dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);+	dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);+	if(debug) {+		mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);+	}+++	/* send action to HAL */+	spin_lock_irqsave(&cesa_lock, flags);+	status = mvCesaAction(cesa_cmd);+	spin_unlock_irqrestore(&cesa_lock, flags);++	/* action not allowed */+	if(status == MV_NOT_ALLOWED) {+#ifdef CESA_OCF_SPLIT+		/* if both encrypt and auth try to split */+		if(auth && (encrypt || decrypt)) {+			MV_CESA_COMMAND	*cesa_cmd_wa;++			/* malloc a new cesa process and init it */	+			cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);+	+        		if (cesa_ocf_cmd_wa == NULL) {+            			printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);+            			goto p_error;+      			}+			memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));+			cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;+			cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;+			cesa_ocf_cmd_wa->need_cb = 0;++			/* break requests to two operation, first operation completion won't call callback */+			if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {+				cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;+				cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;+			}+			else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {+				cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;+				cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;+			}+			else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {+				cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;+				cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;+			}+			else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){+				cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;+				cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;+			}+			else {+				printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);+            			goto p_error;+			}++			/* send the 2 actions to the HAL */+			spin_lock_irqsave(&cesa_lock, flags);+			status = mvCesaAction(cesa_cmd_wa);+			spin_unlock_irqrestore(&cesa_lock, flags);++			if((status != MV_NO_MORE) && (status != MV_OK)) {+				printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);+				goto p_error;+			}+			spin_lock_irqsave(&cesa_lock, flags);+			status = mvCesaAction(cesa_cmd);+			spin_unlock_irqrestore(&cesa_lock, flags);++		}+		/* action not allowed and can't split */+		else +#endif+		{+			goto p_error;+		}+	}++	/* Hal Q is full, send again. This should never happen */+	if(status == MV_NO_RESOURCE) {+		printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);+		if(cesa_ocf_cmd)+			kfree(cesa_ocf_cmd);+		if(cesa_ocf_cmd_wa)+			kfree(cesa_ocf_cmd_wa);+		return ERESTART;+	} +	else if((status != MV_NO_MORE) && (status != MV_OK)) {+                printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);+		goto p_error;+        }+++#ifdef CESA_OCF_POLLING+	cesa_interrupt_polling();+#endif+	cesaTestTraceAdd(5);++	return 0;+p_error:+	crp->crp_etype = EINVAL;+	if(cesa_ocf_cmd)+		kfree(cesa_ocf_cmd);+	if(cesa_ocf_cmd_wa)+		kfree(cesa_ocf_cmd_wa);+       	return EINVAL;+}++/*+ * cesa callback. + */+static void+cesa_callback(unsigned long dummy)+{+	struct cesa_ocf_process *cesa_ocf_cmd = NULL;+	struct cryptop 		*crp = NULL;+	MV_CESA_RESULT  	result[MV_CESA_MAX_CHAN];+	int 			res_idx = 0,i;+	MV_STATUS               status;++	dprintk("%s()\n", __FUNCTION__);++#ifdef CESA_OCF_TASKLET+	disable_irq(cesa_device.irq);+#endif+    while(MV_TRUE) {+	+		 /* Get Ready requests */+		spin_lock(&cesa_lock);+		status = mvCesaReadyGet(&result[res_idx]);+		spin_unlock(&cesa_lock);++	        cesaTestTraceAdd(2);	++		    if(status != MV_OK) {+#ifdef CESA_OCF_POLLING+		        if(status == MV_BUSY) { /* Fragment */+			        cesa_interrupt_polling();+			        return;+		        }+#endif+	    	    break;+    	    }+	        res_idx++;+		    break;+	    }+	+	for(i = 0; i < res_idx; i++) {++		if(!result[i].pReqPrv) {+			printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);+			break;+		}++		cesa_ocf_cmd = result[i].pReqPrv;+		crp = cesa_ocf_cmd->crp; ++		// ignore HMAC error.+		//if(result->retCode)+		//	crp->crp_etype = EIO;	+	+#if  defined(CESA_OCF_POLLING) +		if(!cesa_ocf_cmd->need_cb){+			cesa_interrupt_polling();+		}	+#endif+		if(cesa_ocf_cmd->need_cb) {+			if(debug) {+				mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);+			}+			crypto_done(crp);+		}+		kfree(cesa_ocf_cmd);+    	}+#ifdef CESA_OCF_TASKLET+	enable_irq(cesa_device.irq);+#endif++	cesaTestTraceAdd(3);++	return;+}++#ifdef CESA_OCF_POLLING+static void+cesa_interrupt_polling(void)+{+        u32                  	cause;++	dprintk("%s()\n", __FUNCTION__);++  	/* Read cause register */+	do {+		cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);+		cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;++	} while (cause == 0);+		+	/* clear interrupts */+    	MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);++	cesa_callback(0);++	return;+}++#endif++/*+ * cesa Interrupt polling routine.+ */+static irqreturn_t+cesa_interrupt_handler(int irq, void *arg)+{+        u32                  	cause;++	dprintk("%s()\n", __FUNCTION__);++	cesaTestTraceAdd(0);++  	/* Read cause register */+	cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);++    	if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)+    	{+        /* Empty interrupt */+		dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);+        	return IRQ_HANDLED;+    	}+	+	/* clear interrupts */+    	MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);++	cesaTestTraceAdd(1);+#ifdef CESA_OCF_TASKLET	+	tasklet_hi_schedule(&cesa_ocf_tasklet);+#else+	cesa_callback(0);+#endif+	return IRQ_HANDLED;+}++/*+ * Open a session.+ */+static int +/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/+cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)+{+	u32 status = 0, i;+	u32 count = 0, auth = 0, encrypt =0;+	struct cesa_ocf_data *cesa_ocf_cur_ses;+	MV_CESA_OPEN_SESSION cesa_session;+	MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;+++        dprintk("%s()\n", __FUNCTION__);+        if (sid == NULL || cri == NULL) {+                printk("%s,%d: EINVAL\n", __FILE__, __LINE__);+                return EINVAL;+        }++	/* leave first empty like in other implementations */+        for (i = 1; i < CESA_OCF_MAX_SES; i++) {+       		if (cesa_ocf_sessions[i] == NULL)+               		break;+	}++	if(i >= CESA_OCF_MAX_SES) {+		printk("%s,%d: no more sessions \n", __FILE__, __LINE__);+                return EINVAL;+	}++        cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);+        if (cesa_ocf_sessions[i] == NULL) {+                cesa_ocf_freesession(NULL, i);+                printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);+                return ENOBUFS;+        }+	dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);+	+        *sid = i;+        cesa_ocf_cur_ses = cesa_ocf_sessions[i];+        memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));+	cesa_ocf_cur_ses->sid_encrypt = -1;+	cesa_ocf_cur_ses->sid_decrypt = -1;+	cesa_ocf_cur_ses->frag_wa_encrypt = -1;+	cesa_ocf_cur_ses->frag_wa_decrypt = -1;+	cesa_ocf_cur_ses->frag_wa_auth = -1;++	/* init the session */	+	memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));+	count = 1;+        while (cri) {	+		if(count > 2) {+        		printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);+        		goto error;+		}+                switch (cri->cri_alg) {+		case CRYPTO_AES_CBC:+			dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);+			cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;+			cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;+			cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;+			cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;+			if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {+        			printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);+        			goto error;+			}+			memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);+			dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);+			cesa_ses->cryptoKeyLength = cri->cri_klen/8;+			encrypt += count;+			break;+                case CRYPTO_3DES_CBC:+			dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);+			cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;+			cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;+			cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;+			cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;+			if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {+        			printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);+        			goto error;+			}+			memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);+			cesa_ses->cryptoKeyLength = cri->cri_klen/8;+			encrypt += count;+			break;+                case CRYPTO_DES_CBC:+			dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);+			cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;+			cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;+			cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;+			cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;+			if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {+        			printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);+        			goto error;+			}+			memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);+			cesa_ses->cryptoKeyLength = cri->cri_klen/8;+			encrypt += count;+			break;+                case CRYPTO_MD5:+                case CRYPTO_MD5_HMAC:+			dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");+                        cesa_ocf_cur_ses->auth_alg = cri->cri_alg;+			cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;+			cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;+			if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {+        			printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);+        			goto error;+			}+			cesa_ses->macKeyLength = cri->cri_klen/8;+			memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);+			cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen; +			auth += count;+			break;+                case CRYPTO_SHA1:+                case CRYPTO_SHA1_HMAC:+			dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");+                        cesa_ocf_cur_ses->auth_alg = cri->cri_alg;+			cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12; +			cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;+			if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {+        			printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);+        			goto error;+			}+			cesa_ses->macKeyLength = cri->cri_klen/8;+			memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);+			cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;+			auth += count;+			break;+                default:+                        printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);+                        goto error;+                }+                cri = cri->cri_next;+		count++;+        }++	if((encrypt > 2) || (auth > 2)) {+		printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);+                goto error;+	}+	/* create new sessions in HAL */+	if(encrypt) {+		cesa_ses->operation = MV_CESA_CRYPTO_ONLY;+		/* encrypt session */+		if(auth == 1) {+			cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;+		}+		else if(auth == 2) {+			cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;+			cesa_ocf_cur_ses->encrypt_tn_auth = 1;+		}+		else {+			cesa_ses->operation = MV_CESA_CRYPTO_ONLY;+		}+		cesa_ses->direction = MV_CESA_DIR_ENCODE;+		status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);+    		if(status != MV_OK) {+        		printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);+        		goto error;+    		}	+		/* decrypt session */+		if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {+			cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;+		}+		else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {+			cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;+		}+		cesa_ses->direction = MV_CESA_DIR_DECODE;+		status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);+		if(status != MV_OK) {+        		printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);+        		goto error;+    		}++		/* preapre one action sessions for case we will need to split an action */+#ifdef CESA_OCF_SPLIT+		if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) || +			( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {+			/* open one session for encode and one for decode */+			cesa_ses->operation = MV_CESA_CRYPTO_ONLY;+			cesa_ses->direction = MV_CESA_DIR_ENCODE;+			status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);+    			if(status != MV_OK) {+        			printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);+        			goto error;+    			}++			cesa_ses->direction = MV_CESA_DIR_DECODE;+			status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);+    			if(status != MV_OK) {+        			printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);+        			goto error;+    			}+			/* open one session for auth */	+			cesa_ses->operation = MV_CESA_MAC_ONLY;+			cesa_ses->direction = MV_CESA_DIR_ENCODE;+			status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);+			if(status != MV_OK) {+        			printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);+				goto error;+    			}+		}+#endif+	}+	else { /* only auth */+		cesa_ses->operation = MV_CESA_MAC_ONLY;+		cesa_ses->direction = MV_CESA_DIR_ENCODE;+        	status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);+		if(status != MV_OK) {+        		printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);+			goto error;+    		}+	}+	+        return 0;+error:+     	cesa_ocf_freesession(NULL, *sid);+      	return EINVAL;	++}+++/*+ * Free a session.+ */+static int+cesa_ocf_freesession(device_t dev, u_int64_t tid)+{+        struct cesa_ocf_data *cesa_ocf_cur_ses;+        u_int32_t sid = CRYPTO_SESID2LID(tid);+	//unsigned long flags;++        dprintk("%s() %d \n", __FUNCTION__, sid);+        if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {+                printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);+                return(EINVAL);+        }++        /* Silently accept and return */+        if (sid == 0)+                return(0);++	/* release session from HAL */+	cesa_ocf_cur_ses = cesa_ocf_sessions[sid];+     	if (cesa_ocf_cur_ses->sid_encrypt != -1) {+		mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);+	}+	if (cesa_ocf_cur_ses->sid_decrypt != -1) {+		mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);+	}+     	if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {+		mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);+	}+	if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {+		mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);+	}+	if (cesa_ocf_cur_ses->frag_wa_auth != -1) {+		mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);+	}++      	kfree(cesa_ocf_cur_ses);+	cesa_ocf_sessions[sid] = NULL;++        return 0;+}+++/* TDMA Window setup */++static void __init+setup_tdma_mbus_windows(struct cesa_dev *dev)+{+    int i;+    +    for (i = 0; i < 4; i++) {+        writel(0, dev->reg + WINDOW_BASE(i));+        writel(0, dev->reg + WINDOW_CTRL(i));+    }+    +    for (i = 0; i < dev->plat_data->dram->num_cs; i++) {+        struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;+        writel(+            ((cs->size - 1) & 0xffff0000) |+            (cs->mbus_attr << 8) |+            (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,+            dev->reg + WINDOW_CTRL(i)+        );+        writel(cs->base, dev->reg + WINDOW_BASE(i));+    }+}+                                        +/*+ * our driver startup and shutdown routines+ */+static int+mv_cesa_ocf_init(struct platform_device *pdev)+{+#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)+	if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))+	{+		dprintk("CESA is not mapped to this CPU\n");+		return -ENODEV;+	}		+#endif++	dprintk("%s\n", __FUNCTION__);+	memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));+	softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);+	cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);++	if (cesa_ocf_id < 0)+		panic("MV CESA crypto device cannot initialize!");++	dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);++	/* CESA unit is auto power on off */+#if 0+	if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))+	{+		printk("\nWarning CESA %d is Powered Off\n",0);+		return EINVAL;+	}+#endif++	memset(&cesa_device, 0, sizeof(struct cesa_dev));+	/* Get the IRQ, and crypto memory regions */+	{+		struct resource *res;+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");+		+		if (!res)+			return -ENXIO;+		+		cesa_device.sram = ioremap(res->start, res->end - res->start + 1);+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");+		+		if (!res) {+		        iounmap(cesa_device.sram);+			return -ENXIO;+                }+                cesa_device.reg = ioremap(res->start, res->end - res->start + 1);+		cesa_device.irq = platform_get_irq(pdev, 0);+		cesa_device.plat_data = pdev->dev.platform_data;+	        setup_tdma_mbus_windows(&cesa_device);	+		+	}+	+	+	if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,+				NULL) ) {+            	printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);+		return EINVAL;+	}++	/* clear and unmask Int */+	MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);+#ifndef CESA_OCF_POLLING+    MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);+#endif+#ifdef CESA_OCF_TASKLET+	tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);+#endif+	/* register interrupt */+	if( request_irq( cesa_device.irq, cesa_interrupt_handler,+                             (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {+            	printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);+		return EINVAL;+        }+++	memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);++#define	REGISTER(alg) \+	crypto_register(cesa_ocf_id, alg, 0,0)+	REGISTER(CRYPTO_AES_CBC);+	REGISTER(CRYPTO_DES_CBC);+	REGISTER(CRYPTO_3DES_CBC);+	REGISTER(CRYPTO_MD5);+	REGISTER(CRYPTO_MD5_HMAC);+	REGISTER(CRYPTO_SHA1);+	REGISTER(CRYPTO_SHA1_HMAC);+#undef REGISTER++	return 0;+}++static void+mv_cesa_ocf_exit(struct platform_device *pdev)+{+	dprintk("%s()\n", __FUNCTION__);++	crypto_unregister_all(cesa_ocf_id);+	cesa_ocf_id = -1;+	iounmap(cesa_device.reg);+	iounmap(cesa_device.sram);+	free_irq(cesa_device.irq, NULL);+	+	/* mask and clear Int */+	MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);+	MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);+    	++	if( MV_OK != mvCesaFinish() ) {+            	printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);+		return;+	}+}+++void cesa_ocf_debug(void)+{++#ifdef CESA_OCF_TRACE_DEBUG+    {+        int i, j;+        j = cesaTestTraceIdx;+        mvOsPrintf("No  Type   rCause   iCause   Proc   Isr   Res     Time     pReady    pProc    pEmpty\n");+        for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)+        {+            mvOsPrintf("%02d.  %d   0x%04x   0x%04x   0x%02x   0x%02x   %02d   0x%06x  %p  %p  %p\n",+                j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,+                cesaTestTrace[j].idmaCause, +                cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,+                cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);+            j++;+            if(j == MV_CESA_TEST_TRACE_SIZE)+                j = 0;+        }+    }+#endif++}++static struct platform_driver marvell_cesa = {+	.probe		= mv_cesa_ocf_init,+	.remove		= mv_cesa_ocf_exit,+	.driver		= {+		.owner	= THIS_MODULE,+		.name	= "mv_crypto",+	},+};++MODULE_ALIAS("platform:mv_crypto");++static int __init mv_cesa_init(void)+{+	return platform_driver_register(&marvell_cesa);+}++module_init(mv_cesa_init);++static void __exit mv_cesa_exit(void)+{+	platform_driver_unregister(&marvell_cesa);+}++module_exit(mv_cesa_exit);++MODULE_LICENSE("GPL");+MODULE_AUTHOR("Ronen Shitrit");+MODULE_DESCRIPTION("OCF module for Orion CESA crypto");diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/Makefile linux-2.6.36/crypto/ocf/kirkwood/Makefile--- linux-2.6.36.orig/crypto/ocf/kirkwood/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/Makefile	2010-11-09 20:28:06.092495440 +0100@@ -0,0 +1,19 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o++mv_cesa-y := cesa/mvCesa.o cesa/mvLru.o cesa/mvMD5.o cesa/mvSHA1.o cesa/AES/mvAesAlg.o cesa/AES/mvAesApi.o cesa/mvCesaDebug.o cesa_ocf_drv.o++# Extra objects required by the CESA driver+mv_cesa-y += mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.o mvHal/kw_family/boardEnv/mvBoardEnvLib.o mvHal/mv_hal/twsi/mvTwsi.o mvHal/kw_family/ctrlEnv/sys/mvCpuIf.o mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.o mvHal/kw_family/ctrlEnv/sys/mvSysDram.o mvHal/linux_oss/mvOs.o mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.o mvHal/mv_hal/gpp/mvGpp.o mvHal/kw_family/ctrlEnv/sys/mvSysPex.o mvHal/mv_hal/pex/mvPex.o mvHal/kw_family/boardEnv/mvBoardEnvSpec.o mvHal/common/mvCommon.o mvHal/common/mvDebug.o mvHal/kw_family/ctrlEnv/sys/mvSysCesa.o++ifdef src+EXTRA_CFLAGS += -I$(src)/.. -I$(src)/cesa -I$(src)/mvHal -I$(src)/mvHal/common -I$(src)/mvHal/kw_family -I$(src)/mvHal/mv_hal -I$(src)/mvHal/linux_oss -I$(src)+endif++EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3+ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mv802_3.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mv802_3.h	2010-11-09 20:28:06.131247793 +0100@@ -0,0 +1,213 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmv802_3h+#define __INCmv802_3h+++/* includes */+#include "mvTypes.h"++/* Defines */+#define MV_MAX_ETH_DATA     1500++/* 802.3 types */+#define MV_IP_TYPE                  0x0800+#define MV_IP_ARP_TYPE              0x0806+#define MV_APPLE_TALK_ARP_TYPE      0x80F3+#define MV_NOVELL_IPX_TYPE          0x8137+#define MV_EAPOL_TYPE				0x888e++++/* Encapsulation header for RFC1042 and Ethernet_tunnel */++#define MV_RFC1042_SNAP_HEADER     {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}++#define MV_ETH_SNAP_LSB             0xF8+++#define	MV_MAC_ADDR_SIZE	(6)+#define MV_MAC_STR_SIZE		(20)+#define MV_VLAN_HLEN		(4)++/* This macro checks for a multicast mac address    */+#define MV_IS_MULTICAST_MAC(mac)  (((mac)[0] & 0x1) == 1)+++/* This macro checks for an broadcast mac address     */+#define MV_IS_BROADCAST_MAC(mac)            \+       (((mac)[0] == 0xFF) &&       \+        ((mac)[1] == 0xFF) &&       \+        ((mac)[2] == 0xFF) &&       \+        ((mac)[3] == 0xFF) &&       \+        ((mac)[4] == 0xFF) &&       \+        ((mac)[5] == 0xFF))+++/* Typedefs */+typedef struct+{+    MV_U8     pDA[MV_MAC_ADDR_SIZE];+    MV_U8     pSA[MV_MAC_ADDR_SIZE];+    MV_U16    typeOrLen;++} MV_802_3_HEADER;++enum {+  MV_IP_PROTO_NULL	= 0,    /* Dummy protocol for TCP               */+  MV_IP_PROTO_ICMP	= 1,    /* Internet Control Message Protocol    */+  MV_IP_PROTO_IGMP	= 2,    /* Internet Group Management Protocol   */+  MV_IP_PROTO_IPIP	= 4,    /* IPIP tunnels (older KA9Q tunnels use 94) */+  MV_IP_PROTO_TCP	= 6,    /* Transmission Control Protocol        */+  MV_IP_PROTO_EGP	= 8,    /* Exterior Gateway Protocol            */+  MV_IP_PROTO_PUP	= 12,   /* PUP protocol                         */+  MV_IP_PROTO_UDP	= 17,   /* User Datagram Protocol               */+  MV_IP_PROTO_IDP	= 22,   /* XNS IDP protocol                     */+  MV_IP_PROTO_DCCP	= 33,   /* Datagram Congestion Control Protocol */+  MV_IP_PROTO_IPV6	= 41,   /* IPv6-in-IPv4 tunnelling              */+  MV_IP_PROTO_RSVP	= 46,   /* RSVP protocol                        */+  MV_IP_PROTO_GRE	= 47,   /* Cisco GRE tunnels (rfc 1701,1702)    */+  MV_IP_PROTO_ESP	= 50,   /* Encapsulation Security Payload protocol */+  MV_IP_PROTO_AH	= 51,   /* Authentication Header protocol       */+  MV_IP_PROTO_BEETPH	= 94,   /* IP option pseudo header for BEET     */+  MV_IP_PROTO_PIM	= 103, +  MV_IP_PROTO_COMP	= 108,  /* Compression Header protocol          */+  MV_IP_PROTO_ZERO_HOP	= 114,  /* Any 0 hop protocol (IANA)            */+  MV_IP_PROTO_SCTP	= 132,  /* Stream Control Transport Protocol    */+  MV_IP_PROTO_UDPLITE	= 136,  /* UDP-Lite (RFC 3828)                  */++  MV_IP_PROTO_RAW	= 255,  /* Raw IP packets                       */+  MV_IP_PROTO_MAX+};++typedef struct+{+    MV_U8   version;+    MV_U8   tos;+    MV_U16  totalLength;+    MV_U16  identifier;+    MV_U16  fragmentCtrl;+    MV_U8   ttl;+    MV_U8   protocol;+    MV_U16  checksum;+    MV_U32  srcIP;+    MV_U32  dstIP;++} MV_IP_HEADER; ++typedef struct+{       +    MV_U32 spi;+    MV_U32 seqNum;+} MV_ESP_HEADER; ++#define MV_ICMP_ECHOREPLY          0       /* Echo Reply                   */+#define MV_ICMP_DEST_UNREACH       3       /* Destination Unreachable      */+#define MV_ICMP_SOURCE_QUENCH      4       /* Source Quench                */+#define MV_ICMP_REDIRECT           5       /* Redirect (change route)      */+#define MV_ICMP_ECHO               8       /* Echo Request                 */+#define MV_ICMP_TIME_EXCEEDED      11      /* Time Exceeded                */+#define MV_ICMP_PARAMETERPROB      12      /* Parameter Problem            */+#define MV_ICMP_TIMESTAMP          13      /* Timestamp Request            */+#define MV_ICMP_TIMESTAMPREPLY     14      /* Timestamp Reply              */+#define MV_ICMP_INFO_REQUEST       15      /* Information Request          */+#define MV_ICMP_INFO_REPLY         16      /* Information Reply            */+#define MV_ICMP_ADDRESS            17      /* Address Mask Request         */+#define MV_ICMP_ADDRESSREPLY       18      /* Address Mask Reply           */++typedef struct+{+    MV_U8   type;+    MV_U8   code;+    MV_U16  checksum;+    MV_U16  id;+    MV_U16  sequence;++} MV_ICMP_ECHO_HEADER;++typedef struct+{+    MV_U16  source;+    MV_U16  dest;+    MV_U32  seq;+    MV_U32  ack_seq;+    MV_U16  flags;+    MV_U16  window;+    MV_U16  chksum;+    MV_U16  urg_offset;++} MV_TCP_HEADER;++typedef struct+{+    MV_U16  source;+    MV_U16  dest;+    MV_U16  len;+    MV_U16  check;++} MV_UDP_HEADER;++#endif /* __INCmv802_3h */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.c	2010-11-09 20:28:06.172495450 +0100@@ -0,0 +1,277 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvOs.h"+#include "mv802_3.h"+#include "mvCommon.h"+++/*******************************************************************************+* mvMacStrToHex - Convert MAC format string to hex.+*+* DESCRIPTION:+*		This function convert MAC format string to hex.+*+* INPUT:+*       macStr - MAC address string. Fornat of address string is +*                uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.+*+* OUTPUT:+*       macHex - MAC in hex format.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)+{+    int i;+    char tmp[3];++    for(i = 0; i < MV_MAC_ADDR_SIZE; i++)+    {+        tmp[0] = macStr[(i * 3) + 0];+        tmp[1] = macStr[(i * 3) + 1];+        tmp[2] = '\0';+        macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));+    }+    return MV_OK;+}++/*******************************************************************************+* mvMacHexToStr - Convert MAC in hex format to string format.+*+* DESCRIPTION:+*		This function convert MAC in hex format to string format.+*+* INPUT:+*       macHex - MAC in hex format.+*+* OUTPUT:+*       macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)+{+	int i;++    for(i = 0; i < MV_MAC_ADDR_SIZE; i++)+    {+        mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);+    }+    macStr[(i * 3) - 1] = '\0';++    return MV_OK;+}++/*******************************************************************************+* mvSizePrint - Print the given size with size unit description.+*+* DESCRIPTION:+*		This function print the given size with size unit description.+*       FOr example when size paramter is 0x180000, the function prints:+*       "size 1MB+500KB"+*+* INPUT:+*       size - Size in bytes.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvSizePrint(MV_U32 size)+{+    mvOsOutput("size ");++    if(size >= _1G)+    {+        mvOsOutput("%3dGB ", size / _1G);+        size %= _1G;+        if(size)+            mvOsOutput("+");+    }+    if(size >= _1M )+    {+        mvOsOutput("%3dMB ", size / _1M);+        size %= _1M;+        if(size)+            mvOsOutput("+");+    }+    if(size >= _1K)+    {+        mvOsOutput("%3dKB ", size / _1K);+        size %= _1K;+        if(size)+            mvOsOutput("+");+    }+    if(size > 0)+    {+        mvOsOutput("%3dB ", size);+    }+}++/*******************************************************************************+* mvHexToBin - Convert hex to binary+*+* DESCRIPTION:+*		This function Convert hex to binary.+*+* INPUT:+*       pHexStr - hex buffer pointer.+*       size    - Size to convert.+*+* OUTPUT:+*       pBin - Binary buffer pointer.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)+{+  	int     j, i;+    char    tmp[3];+    MV_U8   byte;+    +    for(j=0, i=0; j<size; j++, i+=2)+    {+        tmp[0] = pHexStr[i];+        tmp[1] = pHexStr[i+1];+        tmp[2] = '\0';+        byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);+        pBin[j] =  byte;     +    }+}++void     mvAsciiToHex(const char* asciiStr, char* hexStr)+{+	int	i=0;++	while(asciiStr[i] != 0)+	{+		mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);+		i++;+	}+	hexStr[i*2] = 0;+}+++void    mvBinToHex(const MV_U8* bin, char* hexStr, int size)+{+	int i;++    for(i=0; i<size; i++)+    {+        mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);+    }+    hexStr[i*2] = '\0';+}++void    mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)+{+	int i;+ +    for(i=0; i<size; i++)+    {+        mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);+    }+    asciiStr[i*2] = '\0';+}++/*******************************************************************************+* mvLog2 - +*+* DESCRIPTION:+*	Calculate the Log2 of a given number.+*+* INPUT:+*       num - A number to calculate the Log2 for.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Log 2 of the input number, or 0xFFFFFFFF if input is 0.+*+*******************************************************************************/+MV_U32 mvLog2(MV_U32	num)+{+	MV_U32 result = 0;+	if(num == 0)+		return 0xFFFFFFFF;+	while(num != 1)+	{+		num = num >> 1;+		result++;+	}+	return result;+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvCommon.h	2010-11-09 20:28:06.212495496 +0100@@ -0,0 +1,308 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++++#ifndef __INCmvCommonh+#define __INCmvCommonh++#include "mvTypes.h"++/* Swap tool */++/* 16bit nibble swap. For example 0x1234 -> 0x2143                          */+#define MV_NIBBLE_SWAP_16BIT(X)    (((X&0xf) << 4) |     \+                                    ((X&0xf0) >> 4) |    \+                                    ((X&0xf00) << 4) |   \+                                    ((X&0xf000) >> 4))+        +/* 32bit nibble swap. For example 0x12345678 -> 0x21436587                  */+#define MV_NIBBLE_SWAP_32BIT(X)    (((X&0xf) << 4) |       \+                                    ((X&0xf0) >> 4) |      \+                                    ((X&0xf00) << 4) |     \+                                    ((X&0xf000) >> 4) |    \+                                    ((X&0xf0000) << 4) |   \+                                    ((X&0xf00000) >> 4) |  \+                                    ((X&0xf000000) << 4) | \+                                    ((X&0xf0000000) >> 4))++/* 16bit byte swap. For example 0x1122 -> 0x2211                            */+#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))++/* 32bit byte swap. For example 0x11223344 -> 0x44332211                    */+#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) |                       \+                               (((X)&0xff00)<<8) |                      \+                               (((X)&0xff0000)>>8) |                    \+                               (((X)&0xff000000)>>24))++/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211  */+#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) |             \+                                      (((X)&0xff00ULL)<<40) |           \+                                      (((X)&0xff0000ULL)<<24) |         \+                                      (((X)&0xff000000ULL)<<8) |        \+                                      (((X)&0xff00000000ULL)>>8) |      \+                                      (((X)&0xff0000000000ULL)>>24) |   \+                                      (((X)&0xff000000000000ULL)>>40) | \+                                      (((X)&0xff00000000000000ULL)>>56)))++/* Endianess macros.                                                        */+#if defined(MV_CPU_LE)+    #define MV_16BIT_LE(X)  (X) +    #define MV_32BIT_LE(X)  (X)+    #define MV_64BIT_LE(X)  (X)+    #define MV_16BIT_BE(X)  MV_BYTE_SWAP_16BIT(X)+    #define MV_32BIT_BE(X)  MV_BYTE_SWAP_32BIT(X)+    #define MV_64BIT_BE(X)  MV_BYTE_SWAP_64BIT(X)+#elif defined(MV_CPU_BE)+    #define MV_16BIT_LE(X)  MV_BYTE_SWAP_16BIT(X) +    #define MV_32BIT_LE(X)  MV_BYTE_SWAP_32BIT(X)+    #define MV_64BIT_LE(X)  MV_BYTE_SWAP_64BIT(X)+    #define MV_16BIT_BE(X)  (X)+    #define MV_32BIT_BE(X)  (X)+    #define MV_64BIT_BE(X)  (X)+#else+    #error "CPU endianess isn't defined!\n"+#endif +++/* Bit field definitions */+#define NO_BIT      0x00000000+#define BIT0        0x00000001+#define BIT1        0x00000002+#define BIT2        0x00000004+#define BIT3        0x00000008+#define BIT4        0x00000010+#define BIT5        0x00000020+#define BIT6        0x00000040+#define BIT7        0x00000080+#define BIT8        0x00000100+#define BIT9        0x00000200+#define BIT10       0x00000400+#define BIT11       0x00000800+#define BIT12       0x00001000+#define BIT13       0x00002000+#define BIT14       0x00004000+#define BIT15       0x00008000+#define BIT16       0x00010000+#define BIT17       0x00020000+#define BIT18       0x00040000+#define BIT19       0x00080000+#define BIT20       0x00100000+#define BIT21       0x00200000+#define BIT22       0x00400000+#define BIT23       0x00800000+#define BIT24       0x01000000+#define BIT25       0x02000000+#define BIT26       0x04000000+#define BIT27       0x08000000+#define BIT28       0x10000000+#define BIT29       0x20000000+#define BIT30       0x40000000+#define BIT31       0x80000000++/* Handy sizes */+#define _1K         0x00000400+#define _2K         0x00000800+#define _4K         0x00001000+#define _8K         0x00002000+#define _16K        0x00004000+#define _32K        0x00008000+#define _64K        0x00010000+#define _128K       0x00020000+#define _256K       0x00040000+#define _512K       0x00080000++#define _1M         0x00100000+#define _2M         0x00200000+#define _4M         0x00400000+#define _8M         0x00800000+#define _16M        0x01000000+#define _32M        0x02000000+#define _64M        0x04000000+#define _128M       0x08000000+#define _256M       0x10000000+#define _512M       0x20000000++#define _1G         0x40000000+#define _2G         0x80000000++/* Tclock and Sys clock define */+#define _100MHz     100000000+#define _125MHz     125000000+#define _133MHz     133333334+#define _150MHz     150000000+#define _160MHz     160000000+#define _166MHz     166666667+#define _175MHz     175000000+#define _178MHz     178000000+#define _183MHz     183333334+#define _187MHz     187000000+#define _192MHz     192000000+#define _194MHz     194000000+#define _200MHz     200000000+#define _233MHz     233333334+#define _250MHz     250000000+#define _266MHz     266666667+#define _300MHz     300000000++/* For better address window table readability */+#define EN			MV_TRUE+#define DIS			MV_FALSE+#define N_A			-1			/* Not applicable */++/* Cache configuration options for memory (DRAM, SRAM, ... ) */++/* Memory uncached, HW or SW cache coherency is not needed */+#define MV_UNCACHED             0   +/* Memory cached, HW cache coherency supported in WriteThrough mode */+#define MV_CACHE_COHER_HW_WT    1+/* Memory cached, HW cache coherency supported in WriteBack mode */+#define MV_CACHE_COHER_HW_WB    2+/* Memory cached, No HW cache coherency, Cache coherency must be in SW */+#define MV_CACHE_COHER_SW       3++               +/* Macro for testing aligment. Positive if number is NOT aligned   */+#define MV_IS_NOT_ALIGN(number, align)      ((number) & ((align) - 1))++/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340   */+#define MV_ALIGN_UP(number, align)                                          \+(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))++/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */+#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))++/* This macro returns absolute value                                        */+#define MV_ABS(number)  (((int)(number) < 0) ? -(int)(number) : (int)(number))+++/* Bit fields manipulation macros                                           */++/* An integer word which its 'x' bit is set                                 */+#define MV_BIT_MASK(bitNum)         (1 << (bitNum) )     ++/* Checks wheter bit 'x' in integer word is set                             */+#define MV_BIT_CHECK(word, bitNum)  ( (word) & MV_BIT_MASK(bitNum) )++/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write)          */+#define MV_BIT_CLEAR(word, bitNum)  ( (word) &= ~(MV_BIT_MASK(bitNum)) )++/* Set bit 'x' in integer word (RMW)                                        */+#define MV_BIT_SET(word, bitNum)    ( (word) |= MV_BIT_MASK(bitNum) )++/* Invert bit 'x' in integer word (RMW)                                     */+#define MV_BIT_INV(word, bitNum)    ( (word) ^= MV_BIT_MASK(bitNum) )++/* Get the min between 'a' or 'b'                                           */+#define MV_MIN(a,b)    (((a) < (b)) ? (a) : (b)) ++/* Get the max between 'a' or 'b'                                           */+#define MV_MAX(a,b)    (((a) < (b)) ? (b) : (a)) ++/* Temporary */+#define mvOsDivide(num, div)        \+({                                  \+    int i=0, rem=(num);             \+                                    \+    while(rem >= (div))             \+    {                               \+        rem -= (div);               \+        i++;                        \+    }                               \+    (i);                            \+})++/* Temporary */+#define mvOsReminder(num, div)      \+({                                  \+    int rem = (num);                \+                                    \+    while(rem >= (div))             \+        rem -= (div);               \+    (rem);                          \+})++#define MV_IP_QUAD(ipAddr)    ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \+                              ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)++#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))++#ifndef MV_ASMLANGUAGE+/* mvCommon API list */++MV_VOID     mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);+void        mvAsciiToHex(const char* asciiStr, char* hexStr);+void        mvBinToHex(const MV_U8* bin, char* hexStr, int size);+void        mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);++MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);+MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);+void        mvSizePrint(MV_U32);++MV_U32 mvLog2(MV_U32 num);++#endif /* MV_ASMLANGUAGE */+++#endif	/* __INCmvCommonh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.c	2010-11-09 20:28:06.252495437 +0100@@ -0,0 +1,326 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++++/* includes */+#include "mvOs.h"+#include "mv802_3.h"+#include "mvCommon.h"+#include "mvDebug.h"++/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros+ * mvDebug  - map of bits (one for each module) bit=1 means enable + *          debug code and messages for this module+ * mvModuleDebug - array of 32 bits varables one for each module+ */+MV_U32    mvDebug = 0;+MV_U32    mvDebugModules[MV_MODULE_MAX];+ +/* Init mvModuleDebug array to default values */+void    mvDebugInit(void)+{+    int     bit;++    mvDebug = 0;+    for(bit=0; bit<MV_MODULE_MAX; bit++)+    {+        mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;+        mvDebug |= MV_BIT_MASK(bit);+    }+}+ +void    mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)+{    +    if (isEnable)+    {+       MV_BIT_SET(mvDebug, module);               +    }+    else+       MV_BIT_CLEAR(mvDebug, module);                   +}+ +void    mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)+{ +    mvDebugModules[module] |= flags;+}++void    mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)+{ +    mvDebugModules[module] &= ~flags;+}++/* Dump memory in specific format: + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8 + */+void mvDebugMemDump(void* addr, int size, int access)+{+    int     i, j;+    MV_U32  memAddr = (MV_U32)addr;++    if(access == 0)+        access = 1;++    if( (access != 4) && (access != 2) && (access != 1) )+    {+        mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",+                    access);+        return;+    }+    memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);+    size = MV_ALIGN_UP(size, 4);+    addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);+    while(size > 0)+    {+        mvOsPrintf("%08x: ", memAddr);+        i = 0;+        /* 32 bytes in the line */+        while(i < 32)+        {+            if(memAddr >= (MV_U32)addr)+            {+                switch(access)+                {+                    case 1:+                        if( memAddr == CPU_PHY_MEM(memAddr) )+                        {+                            mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));+                        }+                        else+                        {+                            mvOsPrintf("%02x ", *((MV_U8*)memAddr));+                        }+                        break;++                    case 2:+                        if( memAddr == CPU_PHY_MEM(memAddr) )+                        {+                            mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));+                        }+                        else+                        {+                            mvOsPrintf("%04x ", *((MV_U16*)memAddr));+                        }+                        break;++                    case 4:+                        if( memAddr == CPU_PHY_MEM(memAddr) )+                        {+                            mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));+                        }+                        else+                        {+                            mvOsPrintf("%08x ", *((MV_U32*)memAddr));+                        }+                        break;+                }+            }+            else+            {+                for(j=0; j<(access*2+1); j++)+                    mvOsPrintf(" ");+            }+            i += access;+            memAddr += access;+            size -= access;+            if(size <= 0)+                break;+        }+        mvOsPrintf("\n");+    }+}++void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)+{+	if(pBufInfo == NULL)+	{+		mvOsPrintf("\n!!! pBufInfo = NULL\n");+		return;+	}+    mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",+               (unsigned int)pBufInfo, +			   (unsigned int)pBufInfo->cmdSts, +			   (unsigned int)pBufInfo->pBuff, +			   (unsigned int)pBufInfo->bufSize);+    mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",+               (unsigned int)pBufInfo->pData, +			   (unsigned int)pBufInfo->byteCnt, +			   (unsigned int)pBufInfo->pNextBufInfo,+               (unsigned int)pBufInfo->userInfo1, +			   (unsigned int)pBufInfo->userInfo2);+    if(pBufInfo->pData != NULL)+    {+        if(size > pBufInfo->byteCnt)+            size = pBufInfo->byteCnt;+        mvDebugMemDump(pBufInfo->pData, size, access);+    }+}++void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)+{+    int frag, len;++	if(pPktInfo == NULL)+	{+		mvOsPrintf("\n!!! pPktInfo = NULL\n");+		return;+	}+    mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",+                pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize, +                pPktInfo->pFrags, pPktInfo->osInfo);+    +    for(frag=0; frag<pPktInfo->numFrags; frag++)+    {+        mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n", +                    frag, pPktInfo->pFrags[frag].bufVirtPtr, +                    pPktInfo->pFrags[frag].bufSize);+        if(size > 0)+        {+            len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);+            mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);+            size -= len;+        }+    }+    +}++void    mvDebugPrintIpAddr(MV_U32 ipAddr)+{+    mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),+                              ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));+}++void    mvDebugPrintMacAddr(const MV_U8* pMacAddr)+{+    int     i;++    mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);+    for(i=1; i<MV_MAC_ADDR_SIZE; i++)+    {+        mvOsPrintf(":%02x", pMacAddr[i]);+    }+    /* mvOsPrintf("\n");*/+}+++/******* There are three functions deals with MV_DEBUG_TIMES structure ********/++/* Reset MV_DEBUG_TIMES entry */+void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)+{+    pTimeEntry->begin = 0;+    pTimeEntry->count = count;+    pTimeEntry->end = 0;+    pTimeEntry->left = pTimeEntry->count;+    pTimeEntry->total = 0;+    pTimeEntry->min = 0xFFFFFFFF;+    pTimeEntry->max = 0x0;+    strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);+    pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';+}++/* Print out MV_DEBUG_TIMES entry */+void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)+{+    int     num;++    if(isTitle == MV_TRUE)+        mvOsPrintf("Event         NumOfEvents       TotalTime         Average       Min       Max\n");++    num = pTimeEntry->count-pTimeEntry->left;+    if(num > 0)+    {+        mvOsPrintf("%-11s     %6u          0x%08lx        %6lu     %6lu    %6lu\n",+                pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,+                pTimeEntry->min, pTimeEntry->max);+    }   +}++/* Update MV_DEBUG_TIMES entry */+void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)+{+    MV_U32  delta;++    if(pTimeEntry->left > 0)                                        +    {                                                                           +        if(pTimeEntry->end <= pTimeEntry->begin)       +        {                                                                       +            delta = pTimeEntry->begin - pTimeEntry->end;+        }+        else+        {+            delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;+        }+        pTimeEntry->total += delta;             ++        if(delta < pTimeEntry->min)    +            pTimeEntry->min = delta;    ++        if(delta > pTimeEntry->max)    +            pTimeEntry->max = delta;      ++        pTimeEntry->left--;                                                                                                                 +    }+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDebug.h	2010-11-09 20:28:06.292495404 +0100@@ -0,0 +1,178 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++++#ifndef __INCmvDebugh+#define __INCmvDebugh++/* includes */+#include "mvTypes.h"++typedef enum +{+    MV_MODULE_INVALID  = -1,+    MV_MODULE_ETH      = 0,+    MV_MODULE_IDMA,+    MV_MODULE_XOR, +    MV_MODULE_TWASI,+    MV_MODULE_MGI,+    MV_MODULE_USB,+    MV_MODULE_CESA,++    MV_MODULE_MAX+}MV_MODULE_ID;+ +/* Define generic flags useful for most of modules */+#define MV_DEBUG_FLAG_ALL   (0)+#define MV_DEBUG_FLAG_INIT  (1 << 0)+#define MV_DEBUG_FLAG_RX    (1 << 1)+#define MV_DEBUG_FLAG_TX    (1 << 2)+#define MV_DEBUG_FLAG_ERR   (1 << 3)+#define MV_DEBUG_FLAG_TRACE (1 << 4)+#define MV_DEBUG_FLAG_DUMP  (1 << 5)+#define MV_DEBUG_FLAG_CACHE (1 << 6)+#define MV_DEBUG_FLAG_IOCTL (1 << 7)+#define MV_DEBUG_FLAG_STATS (1 << 8)++extern MV_U32  mvDebug; +extern MV_U32  mvDebugModules[MV_MODULE_MAX];++#ifdef MV_DEBUG+# define MV_DEBUG_PRINT(module, flags, msg)     mvOsPrintf msg+# define MV_DEBUG_CODE(module, flags, code)     code +#elif defined(MV_RT_DEBUG)+# define MV_DEBUG_PRINT(module, flags, msg)                    \+    if( (mvDebug & (1<<(module))) &&                           \+        ((mvDebugModules[(module)] & (flags)) == (flags)) )    \+        mvOsPrintf msg+# define MV_DEBUG_CODE(module, flags, code)                    \+    if( (mvDebug & (1<<(module))) &&                           \+        ((mvDebugModules[(module)] & (flags)) == (flags)) )    \+        code+#else+# define MV_DEBUG_PRINT(module, flags, msg)+# define MV_DEBUG_CODE(module, flags, code)+#endif++++/* typedefs */++/*  time measurement structure used to check how much time pass between+ *  two points+ */+typedef struct {+    char            name[20];   /* name of the entry */+    unsigned long   begin;      /* time measured on begin point */+    unsigned long   end;        /* time measured on end point */+    unsigned long   total;      /* Accumulated time */+    unsigned long   left;       /* The rest measurement actions */+    unsigned long   count;      /* Maximum measurement actions */+    unsigned long   min;        /* Minimum time from begin to end */+    unsigned long   max;        /* Maximum time from begin to end */+} MV_DEBUG_TIMES;+++/* mvDebug.h API list */++/****** Error Recording ******/++/* Dump memory in specific format: + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8 + */+void mvDebugMemDump(void* addr, int size, int access);++void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);++void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);++void    mvDebugPrintIpAddr(MV_U32 ipAddr);++void mvDebugPrintMacAddr(const MV_U8* pMacAddr);++/**** There are three functions deals with MV_DEBUG_TIMES structure ****/++/* Reset MV_DEBUG_TIMES entry */+void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);++/* Update MV_DEBUG_TIMES entry */+void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);++/* Print out MV_DEBUG_TIMES entry */+void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);+++/******** General ***********/++/* Change value of mvDebugPrint global variable */++void    mvDebugInit(void);+void    mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);+void    mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);+void    mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);+++#endif /* __INCmvDebug.h */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h	2010-11-09 20:28:06.332495486 +0100@@ -0,0 +1,225 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDeviceIdh+#define __INCmvDeviceIdh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* defines  */+#define MARVELL_VEN_ID		    0x11ab++/* Disco-3 */+#define MV64460_DEV_ID          	0x6480+#define MV64460B_DEV_ID         	0x6485+#define MV64430_DEV_ID          	0x6420++/* Disco-5 */+#define MV64560_DEV_ID          	0x6450++/* Disco-6 */+#define MV64660_DEV_ID          	0x6460++/* Orion */        +#define MV_1181_DEV_ID          	0x1181+#define MV_5181_DEV_ID          	0x5181+#define MV_5281_DEV_ID          	0x5281+#define MV_5182_DEV_ID          	0x5182+#define MV_8660_DEV_ID          	0x8660+#define MV_5180_DEV_ID          	0x5180+#define MV_5082_DEV_ID          	0x5082+#define MV_1281_DEV_ID          	0x1281+#define MV_6082_DEV_ID          	0x6082+#define MV_6183_DEV_ID          	0x6183+#define MV_6183L_DEV_ID          	0x6083++#define MV_5281_D0_REV          	0x4+#define MV_5281_D0_ID           	((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)+#define MV_5281_D0_NAME         "88F5281 D0"++#define MV_5281_D1_REV          	0x5+#define MV_5281_D1_ID           	((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)+#define MV_5281_D1_NAME         "88F5281 D1"++#define MV_5281_D2_REV          	0x6+#define MV_5281_D2_ID           	((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)+#define MV_5281_D2_NAME         "88F5281 D2"+++#define MV_5181L_A0_REV         	0x8 /* need for PCIE Er */+#define MV_5181_A1_REV          	0x1 /* for USB Er ..*/+#define MV_5181_B0_REV          	0x2+#define MV_5181_B1_REV          	0x3+#define MV_5182_A1_REV          	0x1+#define MV_5180N_B1_REV         	0x3+#define MV_5181L_A0_ID          	((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)++++/* kw */+#define MV_6281_DEV_ID          	0x6281+#define MV_6192_DEV_ID          	0x6192+#define MV_6190_DEV_ID          	0x6190+#define MV_6180_DEV_ID          	0x6180++#define MV_6281_A0_REV         		0x2+#define MV_6281_A0_ID          		((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)+#define MV_6281_A0_NAME         	"88F6281 A0"++#define MV_6192_A0_REV         		0x2+#define MV_6192_A0_ID          		((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)+#define MV_6192_A0_NAME         	"88F6192 A0"++#define MV_6190_A0_REV         		0x2+#define MV_6190_A0_ID          		((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)+#define MV_6190_A0_NAME         	"88F6190 A0"++#define MV_6180_A0_REV         		0x2+#define MV_6180_A0_ID          		((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)+#define MV_6180_A0_NAME         	"88F6180 A0"++#define MV_6281_A1_REV              0x3+#define MV_6281_A1_ID               ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)+#define MV_6281_A1_NAME             "88F6281 A1"++#define MV_6192_A1_REV              0x3+#define MV_6192_A1_ID               ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)+#define MV_6192_A1_NAME             "88F6192 A1"++#define MV_6190_A1_REV              0x3+#define MV_6190_A1_ID               ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)+#define MV_6190_A1_NAME             "88F6190 A1"++#define MV_6180_A1_REV              0x3+#define MV_6180_A1_ID               ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)+#define MV_6180_A1_NAME             "88F6180 A1" ++#define MV_88F6XXX_A0_REV         	0x2+#define MV_88F6XXX_A1_REV         	0x3+/* Disco-Duo */+#define MV_78XX0_ZY_DEV_ID       0x6381+#define MV_78XX0_ZY_NAME         "MV78X00"++#define MV_78XX0_Z0_REV         0x1+#define MV_78XX0_Z0_ID          ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)+#define MV_78XX0_Z0_NAME        "78X00 Z0"++#define MV_78XX0_Y0_REV         0x2+#define MV_78XX0_Y0_ID          ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)+#define MV_78XX0_Y0_NAME        "78X00 Y0"++#define MV_78XX0_DEV_ID       	0x7800+#define MV_78XX0_NAME         	"MV78X00"++#define MV_76100_DEV_ID      	0x7610+#define MV_78200_DEV_ID      	0x7820+#define MV_78100_DEV_ID      	0x7810+#define MV_78XX0_A0_REV		0x1+#define MV_78XX0_A1_REV		0x2++#define MV_76100_NAME		"MV76100"+#define MV_78100_NAME		"MV78100"+#define MV_78200_NAME		"MV78200"++#define MV_76100_A0_ID		((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)+#define MV_78100_A0_ID		((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)+#define MV_78200_A0_ID		((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)++#define MV_76100_A1_ID		((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)+#define MV_78100_A1_ID		((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)+#define MV_78200_A1_ID		((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)++#define MV_76100_A0_NAME	"MV76100 A0"+#define MV_78100_A0_NAME	"MV78100 A0"+#define MV_78200_A0_NAME	"MV78200 A0"+#define MV_78XX0_A0_NAME	"MV78XX0 A0"++#define MV_76100_A1_NAME	"MV76100 A1"+#define MV_78100_A1_NAME	"MV78100 A1"+#define MV_78200_A1_NAME	"MV78200 A1"+#define MV_78XX0_A1_NAME	"MV78XX0 A1"++/*MV88F632X family*/+#define MV_6321_DEV_ID      	0x6321+#define MV_6322_DEV_ID      	0x6322+#define MV_6323_DEV_ID      	0x6323++#define MV_6321_NAME		"88F6321"+#define MV_6322_NAME		"88F6322"+#define MV_6323_NAME		"88F6323"++#define MV_632X_A1_REV		0x2++#define MV_6321_A1_ID		((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)+#define MV_6322_A1_ID		((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)+#define MV_6323_A1_ID		((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)++#define MV_6321_A1_NAME		"88F6321 A1"+#define MV_6322_A1_NAME		"88F6322 A1"+#define MV_6323_A1_NAME		"88F6323 A1"+++#endif /* __INCmvDeviceIdh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h	2010-11-09 20:28:07.069296580 +0100@@ -0,0 +1,73 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvHalVerh+#define __INCmvHalVerh++/* Defines */+#define MV_HAL_VERSION			"FEROCEON_HAL_3_1_7"+#define MV_RELEASE_BASELINE		"SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"++#endif /* __INCmvHalVerh */\ No newline at end of filediff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.c	2010-11-09 20:28:07.102606889 +0100@@ -0,0 +1,100 @@+/******************************************************************************* +*                   Copyright 2003, Marvell Semiconductor Israel LTD.          * +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL.                      * +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT  * +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE        * +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.     * +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,       * +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.   * +*                                                                              * +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, * +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL    * +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K.  * +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL).                             * +********************************************************************************+* mvQueue.c+*+* FILENAME:    $Workfile: mvStack.c $                     +* REVISION:    $Revision: 1.1 $                              +* LAST UPDATE: $Modtime:  $                  +*                                                          +* DESCRIPTION:                                             +*     This file implements simple Stack LIFO functionality.+*******************************************************************************/++/* includes */+#include "mvOs.h"+#include "mvTypes.h"+#include "mvDebug.h"+#include "mvStack.h"++/* defines  */+++/* Public functions */+++/* Purpose: Create new stack+ * Inputs:+ *	- MV_U32	noOfElements	- maximum number of elements in the stack.+ *                              Each element 4 bytes size+ * Return: void* - pointer to created stack.+ */+void*   mvStackCreate(int numOfElements)+{+	MV_STACK*   pStack;+    MV_U32*     pStackElements;++    pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));+    pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));+    if( (pStack == NULL) || (pStackElements == NULL) )+    {+	    mvOsPrintf("mvStack: Can't create new stack\n");+        return NULL;+    }+    memset(pStackElements, 0, numOfElements*sizeof(MV_U32));+    pStack->numOfElements = numOfElements;+    pStack->stackIdx = 0;+    pStack->stackElements = pStackElements;++	return pStack;+}++/* Purpose: Delete existing stack+ * Inputs:+ *	- void* 	stackHndl 	- Stack handle as returned by "mvStackCreate()" function+ *+ * Return: MV_STATUS  	MV_NOT_FOUND - Failure. StackHandle is not valid.+ *						MV_OK        - Success.+ */+MV_STATUS   mvStackDelete(void* stackHndl)+{+	MV_STACK*   pStack = (MV_STACK*)stackHndl;++	if( (pStack == NULL) || (pStack->stackElements == NULL) )+		return MV_NOT_FOUND;++    mvOsFree(pStack->stackElements);+    mvOsFree(pStack);++    return MV_OK;+}+++/* PrintOut status of the stack */+void    mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)+{+	int			i;+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++    mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",+                stackHndl, pStack->stackElements, pStack->numOfElements, +                pStack->stackIdx);+    if(isPrintElements == MV_TRUE)+    {+        for(i=0; i<pStack->stackIdx; i++)+        {+            mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);+        }+    }+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvStack.h	2010-11-09 20:28:07.160842220 +0100@@ -0,0 +1,140 @@+/******************************************************************************* +*                   Copyright 2003, Marvell Semiconductor Israel LTD.          * +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL.                      * +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT  * +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE        * +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.     * +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,       * +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.   * +*                                                                              * +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, * +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL    * +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K.  * +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL).                             * +********************************************************************************+* mvStack.h - Header File for :+*+* FILENAME:    $Workfile: mvStack.h $+* REVISION:    $Revision: 1.1 $+* LAST UPDATE: $Modtime:  $+*+* DESCRIPTION:+*     This file defines simple Stack (LIFO) functionality.+*+*******************************************************************************/++#ifndef __mvStack_h__+#define __mvStack_h__+++/* includes */+#include "mvTypes.h"+++/* defines  */+++/* typedefs */+/* Data structure describes general purpose Stack */+typedef struct +{+    int     stackIdx;+    int     numOfElements;+    MV_U32* stackElements;+} MV_STACK;++static INLINE MV_BOOL mvStackIsFull(void* stackHndl)+{	+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++    if(pStack->stackIdx == pStack->numOfElements)+        return MV_TRUE;++    return MV_FALSE;+}++static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)+{	+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++    if(pStack->stackIdx == 0)+        return MV_TRUE;++    return MV_FALSE;+}+/* Purpose: Push new element to stack+ * Inputs:+ *	- void* 	stackHndl 	- Stack handle as returned by "mvStackCreate()" function.+ *	- MV_U32	value		- New element.+ *+ * Return: MV_STATUS  	MV_FULL - Failure. Stack is full.+ *						MV_OK   - Success. Element is put to stack.+ */+static INLINE void mvStackPush(void* stackHndl, MV_U32 value)+{	+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++#ifdef MV_RT_DEBUG+    if(pStack->stackIdx == pStack->numOfElements)+    {+        mvOsPrintf("mvStackPush: Stack is FULL\n");+        return;+    }+#endif /* MV_RT_DEBUG */++    pStack->stackElements[pStack->stackIdx] = value;+    pStack->stackIdx++;+}++/* Purpose: Pop element from the top of stack and copy it to "pValue"+ * Inputs:+ *	- void* 	stackHndl 	- Stack handle as returned by "mvStackCreate()" function.+ *	- MV_U32	value		- Element in the top of stack.+ *+ * Return: MV_STATUS  	MV_EMPTY - Failure. Stack is empty.+ *						MV_OK    - Success. Element is removed from the stack and+ *									copied to pValue argument+ */+static INLINE MV_U32   mvStackPop(void* stackHndl)+{+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++#ifdef MV_RT_DEBUG+    if(pStack->stackIdx == 0)+    {+        mvOsPrintf("mvStackPop: Stack is EMPTY\n");+        return 0;+    }+#endif /* MV_RT_DEBUG */++    pStack->stackIdx--;+    return pStack->stackElements[pStack->stackIdx];+}++static INLINE int       mvStackIndex(void* stackHndl)+{+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++    return pStack->stackIdx;+}++static INLINE int       mvStackFreeElements(void* stackHndl)+{+    MV_STACK*   pStack = (MV_STACK*)stackHndl;++    return (pStack->numOfElements - pStack->stackIdx);+}++/* mvStack.h API list */++/* Create new Stack */+void*       mvStackCreate(int numOfElements);++/* Delete existing stack */+MV_STATUS   mvStackDelete(void* stackHndl);++/* Print status of the stack */+void        mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);++#endif /* __mvStack_h__ */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvTypes.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/common/mvTypes.h	2010-11-09 20:28:07.191385803 +0100@@ -0,0 +1,245 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvTypesh+#define __INCmvTypesh++/* Defines */++/* The following is a list of Marvell status    */+#define MV_ERROR		    (-1)+#define MV_OK			    (0x00)  /* Operation succeeded                   */+#define MV_FAIL			    (0x01)	/* Operation failed                      */+#define MV_BAD_VALUE        (0x02)  /* Illegal value (general)               */+#define MV_OUT_OF_RANGE     (0x03)  /* The value is out of range             */+#define MV_BAD_PARAM        (0x04)  /* Illegal parameter in function called  */+#define MV_BAD_PTR          (0x05)  /* Illegal pointer value                 */+#define MV_BAD_SIZE         (0x06)  /* Illegal size                          */+#define MV_BAD_STATE        (0x07)  /* Illegal state of state machine        */+#define MV_SET_ERROR        (0x08)  /* Set operation failed                  */+#define MV_GET_ERROR        (0x09)  /* Get operation failed                  */+#define MV_CREATE_ERROR     (0x0A)  /* Fail while creating an item           */+#define MV_NOT_FOUND        (0x0B)  /* Item not found                        */+#define MV_NO_MORE          (0x0C)  /* No more items found                   */+#define MV_NO_SUCH          (0x0D)  /* No such item                          */+#define MV_TIMEOUT          (0x0E)  /* Time Out                              */+#define MV_NO_CHANGE        (0x0F)  /* Parameter(s) is already in this value */+#define MV_NOT_SUPPORTED    (0x10)  /* This request is not support           */+#define MV_NOT_IMPLEMENTED  (0x11)  /* Request supported but not implemented */+#define MV_NOT_INITIALIZED  (0x12)  /* The item is not initialized           */+#define MV_NO_RESOURCE      (0x13)  /* Resource not available (memory ...)   */+#define MV_FULL             (0x14)  /* Item is full (Queue or table etc...)  */+#define MV_EMPTY            (0x15)  /* Item is empty (Queue or table etc...) */+#define MV_INIT_ERROR       (0x16)  /* Error occured while INIT process      */+#define MV_HW_ERROR         (0x17)  /* Hardware error                        */+#define MV_TX_ERROR         (0x18)  /* Transmit operation not succeeded      */+#define MV_RX_ERROR         (0x19)  /* Recieve operation not succeeded       */+#define MV_NOT_READY	    (0x1A)	/* The other side is not ready yet       */+#define MV_ALREADY_EXIST    (0x1B)  /* Tried to create existing item         */+#define MV_OUT_OF_CPU_MEM   (0x1C)  /* Cpu memory allocation failed.         */+#define MV_NOT_STARTED      (0x1D)  /* Not started yet         */+#define MV_BUSY             (0x1E)  /* Item is busy.                         */+#define MV_TERMINATE        (0x1F)  /* Item terminates it's work.            */+#define MV_NOT_ALIGNED      (0x20)  /* Wrong alignment                       */+#define MV_NOT_ALLOWED      (0x21)  /* Operation NOT allowed                 */+#define MV_WRITE_PROTECT    (0x22)  /* Write protected                       */+++#define MV_INVALID  (int)(-1)++#define MV_FALSE	0+#define MV_TRUE     (!(MV_FALSE))+++#ifndef NULL+#define NULL ((void*)0)+#endif+++#ifndef MV_ASMLANGUAGE+/* typedefs */++typedef char  MV_8;+typedef unsigned char	MV_U8;++typedef int		MV_32;+typedef unsigned int	MV_U32;++typedef short		MV_16;+typedef unsigned short	MV_U16;++#ifdef MV_PPC64+typedef long		MV_64;+typedef unsigned long	MV_U64;+#else+typedef long long		MV_64;+typedef unsigned long long	MV_U64;+#endif++typedef long		MV_LONG;	/* 32/64 */+typedef unsigned long	MV_ULONG;	/* 32/64 */++typedef int     MV_STATUS;+typedef int     MV_BOOL;+typedef void    MV_VOID;+typedef float   MV_FLOAT;++typedef int 	(*MV_FUNCPTR) (void);	  /* ptr to function returning int   */+typedef void 	(*MV_VOIDFUNCPTR) (void); /* ptr to function returning void  */+typedef double 	(*MV_DBLFUNCPTR) (void);  /* ptr to function returning double*/+typedef float 	(*MV_FLTFUNCPTR) (void);  /* ptr to function returning float */++typedef MV_U32 MV_KHZ;+typedef MV_U32 MV_MHZ;+typedef MV_U32 MV_HZ;+++/* This enumerator describes the set of commands that can be applied on   	*/+/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current   	*/+/* status (see MV_STATE enumerator)                      					*/+/* Start can be applied only when status is IDLE                         */+/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED        */+/* Pause can be applied only when status is ACTIVE                          */+/* Restart can be applied only when status is PAUSED                        */+typedef enum _mvCommand+{+    MV_START,              /* Start	*/+    MV_STOP,               /* Stop     */+    MV_PAUSE,              /* Pause    */+    MV_RESTART             /* Restart  */+} MV_COMMAND;++/* This enumerator describes the set of state conditions.					*/+/* Moving from one state to other is stricted.   							*/+typedef enum _mvState+{+    MV_IDLE,+    MV_ACTIVE,+    MV_PAUSED,+    MV_UNDEFINED_STATE+} MV_STATE;+++/* This structure describes address space window. Window base can be        */+/* 64 bit, window size up to 4GB                                            */+typedef struct _mvAddrWin+{+    MV_U32      baseLow;    /* 32bit base low       */+    MV_U32      baseHigh;   /* 32bit base high      */+    MV_U32      size;       /* 32bit size           */+}MV_ADDR_WIN;++/* This binary enumerator describes protection attribute status             */+typedef enum _mvProtRight+{+    ALLOWED,        /* Protection attribute allowed                         */+    FORBIDDEN       /* Protection attribute forbidden                       */+}MV_PROT_RIGHT;++/* Unified struct for Rx and Tx packet operations. The user is required to 	*/+/* be familier only with Tx/Rx descriptor command status.               	*/+typedef struct _bufInfo+{+    MV_U32   cmdSts;        /* Tx/Rx command status                                     */+        MV_U16   byteCnt;       /* Size of valid data in the buffer     */+    MV_U16   bufSize;       /* Total size of the buffer             */+    MV_U8    *pBuff;            /* Pointer to Buffer                    */+    MV_U8    *pData;            /* Pointer to data in the Buffer        */+    MV_U32   userInfo1;         /* Tx/Rx attached user information 1    */+    MV_U32   userInfo2;         /* Tx/Rx attached user information 2    */+    struct _bufInfo *pNextBufInfo;  /* Next buffer in packet            */+} BUF_INFO;++/* This structure contains information describing one of buffers+ * (fragments) they are built Ethernet packet.+ */+typedef struct+{+     MV_U8*	    bufVirtPtr;+     MV_ULONG	bufPhysAddr;+     MV_U32   	bufSize;+     MV_U32     dataSize;+     MV_U32		memHandle;+	 MV_32      bufAddrShift;+} MV_BUF_INFO;++/* This structure contains information describing Ethernet packet.+ * The packet can be divided for few buffers (fragments)+ */+typedef struct+{+    MV_ULONG   	osInfo;+    MV_BUF_INFO *pFrags;+    MV_U32      status;+    MV_U16      pktSize;+    MV_U16      numFrags;+    MV_U32      ownerId;+    MV_U32      fragIP;+} MV_PKT_INFO;++#endif /* MV_ASMLANGUAGE */++#endif /* __INCmvTypesh */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.c	2010-11-09 20:28:07.232495685 +0100@@ -0,0 +1,110 @@+#include <linux/kernel.h>+#include <linux/slab.h>+#include <linux/time.h>+#include "dbg-trace.h"++#define TRACE_ARR_LEN   800+#define STR_LEN         128+struct trace {+    struct timeval tv;+        char str[STR_LEN];+    unsigned int callback_val1;+    unsigned int callback_val2;+        char valid;+};+static unsigned int (*trc_callback1) (unsigned char) = NULL;+static unsigned int (*trc_callback2) (unsigned char) = NULL;+static unsigned char trc_param1 = 0;+static unsigned char trc_param2 = 0;+struct trace *trc_arr;+static int trc_index;+static int trc_active = 0;++void TRC_START()+{+    trc_active = 1;+}++void TRC_STOP()+{+    trc_active = 0;+}++void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)+{+    printk("Marvell debug tracing is on\n");+        trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);+    if(trc_arr == NULL)+    {+        printk("Can't allocate Debug Trace buffer\n");+        return;+    }+        memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));+        trc_index = 0;+    trc_callback1 = callback1;+    trc_callback2 = callback2;+    trc_param1 = callback1_param;+    trc_param2 = callback2_param;+}+void TRC_REC(char *fmt,...)+{+    va_list args;+        struct trace *trc = &trc_arr[trc_index];++    if(trc_active == 0)+        return;++    do_gettimeofday(&trc->tv);+    if(trc_callback1)+        trc->callback_val1 = trc_callback1(trc_param1);+    if(trc_callback2)+        trc->callback_val2 = trc_callback2(trc_param2);+    va_start(args, fmt);+    vsprintf(trc->str,fmt,args);+    va_end(args);+        trc->valid = 1;+        if((++trc_index) == TRACE_ARR_LEN) {+                trc_index = 0;+    }+}+void TRC_OUTPUT(void)+{+        int i,j;+        struct trace *p;+        printk("\n\nTrace %d items\n",TRACE_ARR_LEN);+        for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {+                if(j == TRACE_ARR_LEN)+                        j = 0;+                p = &trc_arr[j];+                if(p->valid) {+            unsigned long uoffs;+            struct trace *plast;+            if(p == &trc_arr[0])+                plast = &trc_arr[TRACE_ARR_LEN-1];+            else+                plast = p-1;+            if(p->tv.tv_sec == ((plast)->tv.tv_sec))+                uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));+            else+                uoffs = (1000000 - ((plast)->tv.tv_usec)) ++                    ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) + +                    p->tv.tv_usec;+                        printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);+            if(trc_callback1)+                printk("[%u]",p->callback_val1);+            if(trc_callback2)+                printk("[%u]",p->callback_val2);+            printk(": %s",p->str);+        }+                p->valid = 0;+        }+        memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));+        trc_index = 0;+}+void TRC_RELEASE(void)+{+        kfree(trc_arr);+        trc_index = 0;+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/dbg-trace.h	2010-11-09 20:28:07.276291416 +0100@@ -0,0 +1,24 @@++#ifndef _MV_DBG_TRCE_H_+#define _MV_DBG_TRCE_H_++#ifdef CONFIG_MV_DBG_TRACE+void TRC_INIT(void *callback1, void *callback2, +    unsigned char callback1_param, unsigned char callback2_param);+void TRC_REC(char *fmt,...);+void TRC_OUTPUT(void);+void TRC_RELEASE(void);+void TRC_START(void);+void TRC_STOP(void);++#else+#define TRC_INIT(x1,x2,x3,x4)+#define TRC_REC(X...)+#define TRC_OUTPUT()+#define TRC_RELEASE()+#define TRC_START()+#define TRC_STOP()+#endif+++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c	2010-11-09 20:28:07.327371127 +0100@@ -0,0 +1,2513 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "boardEnv/mvBoardEnvLib.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "cpu/mvCpu.h"+#include "cntmr/mvCntmr.h"+#include "gpp/mvGpp.h"+#include "twsi/mvTwsi.h"+#include "pex/mvPex.h"+#include "device/mvDevice.h"+#include "eth/gbe/mvEthRegs.h"++/* defines  */+/* #define MV_DEBUG */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif++extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];++#define CODE_IN_ROM		MV_FALSE+#define CODE_IN_RAM		MV_TRUE++extern	MV_BOARD_INFO*	boardInfoTbl[];+#define BOARD_INFO(boardId)	boardInfoTbl[boardId - BOARD_ID_BASE]++/* Locals */+static MV_DEV_CS_INFO*  boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);++MV_U32 tClkRate   = -1;+++/*******************************************************************************+* mvBoardEnvInit - Init board+*+* DESCRIPTION:+*		In this function the board environment take care of device bank+*		initialization.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvBoardEnvInit(MV_VOID)+{+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardEnvInit:Board unknown.\n");+		return;++	}++	/* Set GPP Out value */+	MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);+	MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);++	/* set GPP polarity */+	mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);+	mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);++    /* Workaround for Erratum FE-MISC-70*/+    if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)+    {+        BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;+        BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;+    } /*End of WA*/++	/* Set GPP Out Enable*/+	mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);+	mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);++	/* Nand CE */+	MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);+}++/*******************************************************************************+* mvBoardModelGet - Get Board model+*+* DESCRIPTION:+*       This function returns 16bit describing board model.+*       Board model is constructed of one byte major and minor numbers in the+*       following manner:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       String describing board model.+*+*******************************************************************************/+MV_U16 mvBoardModelGet(MV_VOID)+{+	return (mvBoardIdGet() >> 16);+}++/*******************************************************************************+* mbBoardRevlGet - Get Board revision+*+* DESCRIPTION:+*       This function returns a 32bit describing the board revision.+*       Board revision is constructed of 4bytes. 2bytes describes major number+*       and the other 2bytes describes minor munber.+*       For example for board revision 3.4 the function will return+*       0x00030004.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       String describing board model.+*+*******************************************************************************/+MV_U16 mvBoardRevGet(MV_VOID)+{+	return (mvBoardIdGet() & 0xFFFF);+}++/*******************************************************************************+* mvBoardNameGet - Get Board name+*+* DESCRIPTION:+*       This function returns a string describing the board model and revision.+*       String is extracted from board I2C EEPROM.+*+* INPUT:+*       None.+*+* OUTPUT:+*       pNameBuff - Buffer to contain board name string. Minimum size 32 chars.+*+* RETURN:+*+*       MV_ERROR if informantion can not be read.+*******************************************************************************/+MV_STATUS mvBoardNameGet(char *pNameBuff)+{+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsSPrintf (pNameBuff, "Board unknown.\n");+		return MV_ERROR;++	}++	mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);++	return MV_OK;+}++/*******************************************************************************+* mvBoardIsPortInSgmii -+*+* DESCRIPTION:+*       This routine returns MV_TRUE for port number works in SGMII or MV_FALSE+*	For all other options.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE - port in SGMII.+*       MV_FALSE - other.+*+*******************************************************************************/+MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)+{+    MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;++    if(ethPortNum >= BOARD_ETH_PORT_NUM)+    {+	    mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);+		return MV_FALSE;+    }+    return ethPortSgmiiSupport[ethPortNum];+}++/*******************************************************************************+* mvBoardIsPortInGmii -+*+* DESCRIPTION:+*       This routine returns MV_TRUE for port number works in GMII or MV_FALSE+*	For all other options.+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE - port in GMII.+*       MV_FALSE - other.+*+*******************************************************************************/+MV_BOOL mvBoardIsPortInGmii(MV_VOID)+{+	MV_U32 devClassId, devClass = 0;+	if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)+	{+		/* Get MPP module ID */+		devClassId = mvBoarModuleTypeGet(devClass);+		if (MV_BOARD_MODULE_GMII_ID == devClassId)+			return MV_TRUE;+	}+	else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)+		return MV_TRUE;++    return MV_FALSE;+}+/*******************************************************************************+* mvBoardPhyAddrGet - Get the phy address+*+* DESCRIPTION:+*       This routine returns the Phy address of a given ethernet port.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit describing Phy address, -1 if the port number is wrong.+*+*******************************************************************************/+MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)+{+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");+		return MV_ERROR;+	}++	return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;+}++/*******************************************************************************+* mvBoardMacSpeedGet - Get the Mac speed+*+* DESCRIPTION:+*       This routine returns the Mac speed if pre define of a given ethernet port.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BOARD_MAC_SPEED, -1 if the port number is wrong.+*+*******************************************************************************/+MV_BOARD_MAC_SPEED      mvBoardMacSpeedGet(MV_U32 ethPortNum)+{+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");+		return MV_ERROR;+	}++	return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;+}++/*******************************************************************************+* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication+*+* DESCRIPTION:+*       This routine returns the IRQ number for the link status indication.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       the number of the IRQ for the link status indication, -1 if the port +*	number is wrong or if not relevant.+*+*******************************************************************************/+MV_32	mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)+{+	MV_U32 boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");+		return MV_ERROR;+	}++	return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;+}++/*******************************************************************************+* mvBoardSwitchPortGet - Get the mapping between the board connector and the +* Ethernet Switch port+*+* DESCRIPTION:+*       This routine returns the matching Switch port.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*	boardPortNum - logical number of the connector on the board+*+* OUTPUT:+*       None.+*+* RETURN:+*       the matching Switch port, -1 if the port number is wrong or if not relevant.+*+*******************************************************************************/+MV_32	mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)+{+	MV_U32 boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");+		return MV_ERROR;+	}+	if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)+	{+		mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");+		return MV_ERROR;+	}++	return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];+}++/*******************************************************************************+* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port+*+* DESCRIPTION:+*       This routine returns the Switch CPU port.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       the Switch CPU port, -1 if the port number is wrong or if not relevant.+*+*******************************************************************************/+MV_32	mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)+{+	MV_U32 boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");+		return MV_ERROR;+	}++	return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;+}++/*******************************************************************************+* mvBoardIsSwitchConnected - Get switch connection status +* DESCRIPTION:+*       This routine returns port's connection status+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       1 - if ethPortNum is connected to switch, 0 otherwise+*+*******************************************************************************/+MV_32	mvBoardIsSwitchConnected(MV_U32 ethPortNum)+{+	MV_U32 boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");+		return MV_ERROR;+	}++	if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)+	{+		mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);+		return MV_ERROR;+	}+	+	if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))	+	return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);+	else+		return 0;+}+/*******************************************************************************+* mvBoardSmiScanModeGet - Get Switch SMI scan mode+*+* DESCRIPTION:+*       This routine returns Switch SMI scan mode.+*+* INPUT:+*       ethPortNum - Ethernet port number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.+*+*******************************************************************************/+MV_32	mvBoardSmiScanModeGet(MV_U32 ethPortNum)+{+	MV_U32 boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");+		return MV_ERROR;+	}++	return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;+}+/*******************************************************************************+* mvBoardSpecInitGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN: Return MV_TRUE and parameters in case board need spesific phy init, +* 	  otherwise return MV_FALSE. +*+*+*******************************************************************************/++MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)+{+	return MV_FALSE;+}++/*******************************************************************************+* mvBoardTclkGet - Get the board Tclk (Controller clock)+*+* DESCRIPTION:+*       This routine extract the controller core clock.+*       This function uses the controller counters to make identification.+*		Note: In order to avoid interference, make sure task context switch+*		and interrupts will not occure during this function operation+*+* INPUT:+*       countNum - Counter number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit clock cycles in Hertz.+*+*******************************************************************************/+MV_U32 mvBoardTclkGet(MV_VOID)+{+    if(mvCtrlModelGet()==MV_6281_DEV_ID)+    {+#if defined(TCLK_AUTO_DETECT)+	MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;++    tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);+    tmpTClkRate &= MSAR_TCLCK_MASK;++    switch (tmpTClkRate)+    {+    case MSAR_TCLCK_166:+            return MV_BOARD_TCLK_166MHZ;+            break;+    case MSAR_TCLCK_200:+            return MV_BOARD_TCLK_200MHZ;+            break;+    }+#else+    return MV_BOARD_TCLK_200MHZ;+#endif+    }++        return MV_BOARD_TCLK_166MHZ;++}+/*******************************************************************************+* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)+*+* DESCRIPTION:+*       This routine extract the CPU bus clock.+*+* INPUT:+*       countNum - Counter number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit clock cycles in Hertz.+*+*******************************************************************************/+static MV_U32  mvBoard6180SysClkGet(MV_VOID)+{+	MV_U32 	sysClkRate=0;+	MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;++	sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);+	sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;+	sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;+			+	sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;++	return sysClkRate;++}++MV_U32  mvBoardSysClkGet(MV_VOID)+{+#ifdef SYSCLK_AUTO_DETECT+	MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;+	MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;+	MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;++	if(mvCtrlModelGet() == MV_6180_DEV_ID)+		return mvBoard6180SysClkGet();++	tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);+	pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);+	pClkRate = cpuCLK[pClkRate];++	indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;+	indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;+    if(ddrRtio[indexDdrRtio][0] != 0)+        sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);+    else+        sysClkRate = 0;+	return sysClkRate;+#else+	return MV_BOARD_DEFAULT_SYSCLK;+#endif+}+++/*******************************************************************************+* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number+*+* DESCRIPTION:+*		Multi-ported PCI Express bridges that is implemented on the board+*		collapse interrupts across multiple conventional PCI/PCI-X buses.+*		A dual-headed PCI Express bridge would map (or "swizzle") the+*		interrupts per the following table (in accordance with the respective+*		logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#+*		signals from its two logical PCI/PCI-X bridges, collapse the+*		INTA#-INTD# signals from any internal sources, and convert the+*		signals to in-band PCI Express messages. 10+*		This function returns the upstream interrupt as it was converted by+*		the bridge, according to board configuration and the following table:+*					  		PCI dev num+*			Interrupt pin 	7, 	8, 	9+*		   			A  ->	A	D	C+*		   			B  -> 	B	A	D+*		   			C  -> 	C	B	A+*		  			D  ->	D	C	B+*+*+* INPUT:+*       devNum - PCI/PCIX device number.+*       intPin - PCI Int pin+*+* OUTPUT:+*       None.+*+* RETURN:+*       Int pin connected to the Interrupt controller+*+*******************************************************************************/+MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)+{+	MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );++	if (realIntPin == 0) return 4;+		else return realIntPin;++}++/*******************************************************************************+* mvBoardDebugLedNumGet - Get number of debug Leds+*+* DESCRIPTION:+* INPUT:+*       boardId+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)+{+	return BOARD_INFO(boardId)->activeLedsNumber;+}++/*******************************************************************************+* mvBoardDebugLeg - Set the board debug Leds+*+* DESCRIPTION: turn on/off status leds.+* 	       Note: assume MPP leds are part of group 0 only.+*+* INPUT:+*       hexNum - Number to be displied in hex by Leds.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvBoardDebugLed(MV_U32 hexNum)+{+    MV_U32 val = 0,totalMask, currentBitMask = 1,i;+    MV_U32 boardId= mvBoardIdGet();++    if (BOARD_INFO(boardId)->pLedGppPin == NULL)+	return;++    totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;+    hexNum &= totalMask;+    totalMask = 0;++    for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)+    {+	if (hexNum & currentBitMask)+	{+	    val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);+	}++	totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);++	currentBitMask = (currentBitMask << 1);+    }++    if (BOARD_INFO(boardId)->ledsPolarity)+    {+	mvGppValueSet(0, totalMask, val);+    }+    else+    {+	mvGppValueSet(0, totalMask, ~val);+    }+}+++/*******************************************************************************+* mvBoarGpioPinGet - mvBoarGpioPinGet+*+* DESCRIPTION:+*+* INPUT:+*		class - MV_BOARD_GPP_CLASS enum.+*+* OUTPUT:+*		None.+*+* RETURN:+*       GPIO pin number. The function return -1 for bad parameters.+*+*******************************************************************************/+MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)+{+	MV_U32 boardId, i;+	MV_U32 indexFound = 0;++	boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");+		return MV_ERROR;++	}++        for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)+		if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {+			if (indexFound == index)+        			return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;+			else+				indexFound++;++		}++	return MV_ERROR;+}+++/*******************************************************************************+* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet+*+* DESCRIPTION:+*+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*       GPIO pin number. The function return -1 for bad parameters.+*+*******************************************************************************/+MV_32 mvBoardRTCGpioPinGet(MV_VOID)+{+	return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);+}+++/*******************************************************************************+* mvBoardReset - mvBoardReset+*+* DESCRIPTION:+*			Reset the board+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*       None+*+*******************************************************************************/+MV_VOID	mvBoardReset(MV_VOID)+{+	MV_32 resetPin;++	/* Get gpp reset pin if define */+	resetPin = mvBoardResetGpioPinGet();+	if (resetPin != MV_ERROR)+	{+        	MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));+		MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));++	}+	else+	{+	    /* No gpp reset pin was found, try to reset ussing+	    system reset out */+	    MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);+	    MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);+	}+}++/*******************************************************************************+* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet+*+* DESCRIPTION:+*+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*       GPIO pin number. The function return -1 for bad parameters.+*+*******************************************************************************/+MV_32 mvBoardResetGpioPinGet(MV_VOID)+{+	return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);+}+/*******************************************************************************+* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet+*+* DESCRIPTION:+*	used for hotswap detection+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*       GPIO pin number. The function return -1 for bad parameters.+*+*******************************************************************************/+MV_32  mvBoardSDIOGpioPinGet(MV_VOID)+{+	return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);+}++/*******************************************************************************+* mvBoardUSBVbusGpioPinGet - return Vbus input GPP+*+* DESCRIPTION:+*+* INPUT:+*		int  devNo.+*+* OUTPUT:+*		None.+*+* RETURN:+*       GPIO pin number. The function return -1 for bad parameters.+*+*******************************************************************************/+MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)+{+	return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);+}++/*******************************************************************************+* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP+*+* DESCRIPTION:+*+* INPUT:+*		int  devNo.+*+* OUTPUT:+*		None.+*+* RETURN:+*       GPIO pin number. The function return -1 for bad parameters.+*+*******************************************************************************/+MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)+{+	return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);+}+++/*******************************************************************************+* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins+*+* DESCRIPTION:+*		This function returns a 32-bit mask of GPP pins that connected to+*		interrupt generating sources on board.+*		For example if UART channel A is hardwired to GPP pin 8 and+*		UART channel B is hardwired to GPP pin 4 the fuinction will return+*		the value 0x000000110+*+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*		See description. The function return -1 if board is not identified.+*+*******************************************************************************/+MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)+{+	MV_U32 boardId;++	boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");+		return MV_ERROR;++	}++	return BOARD_INFO(boardId)->intsGppMaskLow;+}+MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)+{+	MV_U32 boardId;++	boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");+		return MV_ERROR;++	}++	return BOARD_INFO(boardId)->intsGppMaskHigh;+}+++/*******************************************************************************+* mvBoardMppGet - Get board dependent MPP register value+*+* DESCRIPTION:+*		MPP settings are derived from board design.+*		MPP group consist of 8 MPPs. An MPP group represent MPP+*		control register.+*       This function retrieves board dependend MPP register value.+*+* INPUT:+*       mppGroupNum - MPP group number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit value describing MPP control register value.+*+*******************************************************************************/+MV_32 mvBoardMppGet(MV_U32 mppGroupNum)+{+	MV_U32 boardId;++	boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardMppGet:Board unknown.\n");+		return MV_ERROR;++	}++	return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];+}+++/*******************************************************************************+* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/+MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)+{++	MV_BOARD_MPP_GROUP_CLASS devClass;+	MV_BOARD_MODULE_ID_CLASS devClassId;+	MV_BOARD_MPP_TYPE_CLASS mppGroupType;+	MV_U32 devId;+	MV_U32 maxMppGrp = 1;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			maxMppGrp = MV_6281_MPP_MAX_MODULE;+			break;+		case MV_6192_DEV_ID:+			maxMppGrp = MV_6192_MPP_MAX_MODULE;+			break;+        case MV_6190_DEV_ID:+            maxMppGrp = MV_6190_MPP_MAX_MODULE;+            break;+		case MV_6180_DEV_ID:+			maxMppGrp = MV_6180_MPP_MAX_MODULE;+			break;		+	}++	for (devClass = 0; devClass < maxMppGrp; devClass++)+	{+		/* If MPP group can be defined by the module connected to it */+		if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)+		{+			/* Get MPP module ID */+			devClassId = mvBoarModuleTypeGet(devClass);+			if (MV_ERROR != devClassId)+			{+				switch(devClassId)+				{+				case MV_BOARD_MODULE_TDM_ID:+				case MV_BOARD_MODULE_TDM_5CHAN_ID:+					mppGroupType = MV_BOARD_TDM;+					break;+				case MV_BOARD_MODULE_AUDIO_ID:+					mppGroupType = MV_BOARD_AUDIO;+					break;+				case MV_BOARD_MODULE_RGMII_ID:+					mppGroupType = MV_BOARD_RGMII;+					break;+				case MV_BOARD_MODULE_GMII_ID:+					mppGroupType = MV_BOARD_GMII;+					break;+				case MV_BOARD_MODULE_TS_ID:+					mppGroupType = MV_BOARD_TS;+					break;+				case MV_BOARD_MODULE_MII_ID:+					mppGroupType = MV_BOARD_MII;+					break;+				default:+					mppGroupType = MV_BOARD_OTHER;+					break;+				}+			}+			else+				/* The module bay is empty */+				mppGroupType = MV_BOARD_OTHER;+			+			/* Update MPP group type */+			mvBoardMppGroupTypeSet(devClass, mppGroupType);+		}++		/* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */+		if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))+			MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);+        	else +		{+			if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))+        		{+				MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);+            			MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);+            			MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);+        		}+        		else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))+        		{+				/* Assumption that the MDC & MDIO should be 3.3V */+				MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);+				/* Assumption that only ETH1 can be MII when using modules on DB */+            			MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);+        		}+		}+	}+}++/*******************************************************************************+* mvBoardMppGroupTypeGet +*+* DESCRIPTION:+*+* INPUT:+*       mppGroupClass - MPP group number 0  for MPP[35:20] or 1 for MPP[49:36].+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/+MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)+{+	MV_U32 boardId;++	boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardMppGet:Board unknown.\n");+		return MV_ERROR;++	}+	+	if (mppGroupClass == MV_BOARD_MPP_GROUP_1)+		return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;+	else+		return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;+}++/*******************************************************************************+* mvBoardMppGroupTypeSet +*+* DESCRIPTION:+*+* INPUT:+*       mppGroupClass - MPP group number 0  for MPP[35:20] or 1 for MPP[49:36].+*       mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/+MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,+						MV_BOARD_MPP_TYPE_CLASS mppGroupType)+{+	MV_U32 boardId;++	boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardMppGet:Board unknown.\n");+	}++	if (mppGroupClass == MV_BOARD_MPP_GROUP_1)+		BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;+	else+		BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;++}++/*******************************************************************************+* mvBoardMppMuxSet - Update MPP mux+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/+MV_VOID mvBoardMppMuxSet(MV_VOID)+{++	MV_BOARD_MPP_GROUP_CLASS devClass;+	MV_BOARD_MPP_TYPE_CLASS mppGroupType;+	MV_U32 devId;+	MV_U8 muxVal = 0xf;+	MV_U32 maxMppGrp = 1;+    MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			maxMppGrp = MV_6281_MPP_MAX_MODULE;+			break;+		case MV_6192_DEV_ID:+			maxMppGrp = MV_6192_MPP_MAX_MODULE;+			break;+        case MV_6190_DEV_ID:+            maxMppGrp = MV_6190_MPP_MAX_MODULE;+            break;+		case MV_6180_DEV_ID:+			maxMppGrp = MV_6180_MPP_MAX_MODULE;+			break;		+	}++	for (devClass = 0; devClass < maxMppGrp; devClass++)+	{+		mppGroupType = mvBoardMppGroupTypeGet(devClass);++		switch(mppGroupType)+		{+			case MV_BOARD_TDM:+				muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);+				break;+			case MV_BOARD_AUDIO:+				 muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/+				break;+			case MV_BOARD_TS:+				 muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);+				break;+			default:+				muxVal |= (devClass ? 0xf : 0);+				break;+		}+	}++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: twsi exp set\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);+    	twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);+    	twsiSlave.validOffset = MV_TRUE;+	/* Offset is the first command after the address which indicate the register number to be read +	   in next operation */+    	twsiSlave.offset = 2;+    	twsiSlave.moreThen256 = MV_FALSE;++++    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp out val fail\n"));+        	return;+    	}+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));+    	+	/* Change twsi exp to output */+    	twsiSlave.offset = 6;+	muxVal = 0;+	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp change to out fail\n"));+        	return;+    	}+    	DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));+	+}++/*******************************************************************************+* mvBoardTdmMppSet - set MPPs in TDM module+*+* DESCRIPTION:+*+* INPUT: type of second telephony device+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/+MV_VOID mvBoardTdmMppSet(MV_32 chType)+{++	MV_BOARD_MPP_GROUP_CLASS devClass;+	MV_BOARD_MPP_TYPE_CLASS mppGroupType;+	MV_U32 devId;+	MV_U8 muxVal = 1;+	MV_U8 muxValMask = 1;+	MV_U8 twsiVal;+	MV_U32 maxMppGrp = 1;+    	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			maxMppGrp = MV_6281_MPP_MAX_MODULE;+			break;+		case MV_6192_DEV_ID:+			maxMppGrp = MV_6192_MPP_MAX_MODULE;+			break;+        case MV_6190_DEV_ID:+            maxMppGrp = MV_6190_MPP_MAX_MODULE;+            break;+		case MV_6180_DEV_ID:+			maxMppGrp = MV_6180_MPP_MAX_MODULE;+			break;		+	}++	for (devClass = 0; devClass < maxMppGrp; devClass++)+	{+		mppGroupType = mvBoardMppGroupTypeGet(devClass);+		if(mppGroupType == MV_BOARD_TDM)+			break;+	}++	if(devClass == maxMppGrp)+		return;		/* TDM module not found */++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: twsi exp set\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);+    	twsiSlave.slaveAddr.type = ADDR7_BIT;+    	twsiSlave.validOffset = MV_TRUE;+	/* Offset is the first command after the address which indicate the register number to be read +	   in next operation */+    	twsiSlave.offset = 3;+    	twsiSlave.moreThen256 = MV_FALSE;++	if(mvBoardIdGet() == RD_88F6281A_ID)+	{+		muxVal = 0xc;+		muxValMask = 0xf3;+	}++	mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        muxVal = (twsiVal & muxValMask) | muxVal;++    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		mvOsPrintf("Board: twsi exp out val fail\n");+        	return;+    	}+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));+    	+	/* Change twsi exp to output */+    	twsiSlave.offset = 7;+	muxVal = 0xfe;+	if(mvBoardIdGet() == RD_88F6281A_ID)+		muxVal = 0xf3;++	mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+	muxVal = (twsiVal & muxVal);++	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		mvOsPrintf("Board: twsi exp change to out fail\n");+        	return;+    	}+    	DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));+	/* reset the line to 0 */+    	twsiSlave.offset = 3;+	muxVal = 0;+	muxValMask = 1;++	if(mvBoardIdGet() == RD_88F6281A_ID) {+		muxVal = 0x0;+		muxValMask = 0xf3;+	}++	mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        muxVal = (twsiVal & muxValMask) | muxVal;++    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		mvOsPrintf("Board: twsi exp out val fail\n");+        	return;+    	}+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));++	mvOsDelay(20);++	/* set the line to 1 */+    	twsiSlave.offset = 3;+	muxVal = 1;+	muxValMask = 1;++	if(mvBoardIdGet() == RD_88F6281A_ID)+	{+		muxVal = 0xc;+		muxValMask = 0xf3;+		if(chType) /* FXS - issue reset properly */+		{+			MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);+			mvOsDelay(50);+			MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);+		}+		else /* FXO - issue reset via TDM_CODEC_RST*/+		{+		   /* change MPP44 type to TDM_CODEC_RST(0x2) */+		   MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF)  | BIT17));	+		}	+	}++	mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        muxVal = (twsiVal & muxValMask) | muxVal;++    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		mvOsPrintf("Board: twsi exp out val fail\n");+        	return;+    	}++	/* TBD - 5 channels */+#if defined(MV_TDM_5CHANNELS)+	/* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */+	MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));+	mvGppPolaritySet(1, MV_GPP6, 0);+	+	twsiSlave.offset = 6;+	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);++	mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+	muxVal = (twsiVal & ~BIT2);++	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		mvOsPrintf("Board: twsi exp change to out fail\n");+        	return;+    	}+++	twsiSlave.offset = 2;++	mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+	muxVal = (twsiVal & ~BIT2);++	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )+    	{+    		mvOsPrintf("Board: twsi exp change to out fail\n");+        	return;+    	}+#endif+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));++	+}+/*******************************************************************************+* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes  +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/++MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)+{+	switch(mvBoardIdGet())+	{+		case RD_88F6281A_ID:+			*connMode = DAISY_CHAIN_MODE;+			*irqMode = INTERRUPT_TO_TDM;+			break;+		case DB_88F6281A_BP_ID:+			 *connMode = DUAL_CHIP_SELECT_MODE;+			 *irqMode = INTERRUPT_TO_TDM;+			break;+		case RD_88F6192A_ID:+			*connMode = DUAL_CHIP_SELECT_MODE;+			*irqMode = INTERRUPT_TO_TDM;+			break;+		case DB_88F6192A_BP_ID:+			 *connMode = DUAL_CHIP_SELECT_MODE;+			 *irqMode = INTERRUPT_TO_TDM;+			break;+		default:+			*connMode = *irqMode = -1;+			mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());+	}+		return;+	+}++/*******************************************************************************+* mvBoardMppModuleTypePrint - print module detect+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/+MV_VOID mvBoardMppModuleTypePrint(MV_VOID)+{++	MV_BOARD_MPP_GROUP_CLASS devClass;+	MV_BOARD_MPP_TYPE_CLASS mppGroupType;+	MV_U32 devId;+	MV_U32 maxMppGrp = 1;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			maxMppGrp = MV_6281_MPP_MAX_MODULE;+			break;+		case MV_6192_DEV_ID:+			maxMppGrp = MV_6192_MPP_MAX_MODULE;+			break;+        case MV_6190_DEV_ID:+            maxMppGrp = MV_6190_MPP_MAX_MODULE;+            break;+		case MV_6180_DEV_ID:+			maxMppGrp = MV_6180_MPP_MAX_MODULE;+			break;		+	}++	for (devClass = 0; devClass < maxMppGrp; devClass++)+	{+		mppGroupType = mvBoardMppGroupTypeGet(devClass);++		switch(mppGroupType)+		{+			case MV_BOARD_TDM:+                if(devId != MV_6190_DEV_ID)+                    mvOsPrintf("Module %d is TDM\n", devClass);+				break;+			case MV_BOARD_AUDIO:+                if(devId != MV_6190_DEV_ID)+                    mvOsPrintf("Module %d is AUDIO\n", devClass);+				break;+            case MV_BOARD_RGMII:+                if(devId != MV_6190_DEV_ID)+                    mvOsPrintf("Module %d is RGMII\n", devClass);+				break;+			case MV_BOARD_GMII:+                if(devId != MV_6190_DEV_ID)+                    mvOsPrintf("Module %d is GMII\n", devClass);+				break;+			case MV_BOARD_TS:+                if(devId != MV_6190_DEV_ID)+                    mvOsPrintf("Module %d is TS\n", devClass);+				break;+			default:+				break;+		}+	}+}++/* Board devices API managments */++/*******************************************************************************+* mvBoardGetDeviceNumber - Get number of device of some type on the board+*+* DESCRIPTION:+*+* INPUT:+*		devType - The device type ( Flash,RTC , etc .. )+*+* OUTPUT:+*       None.+*+* RETURN:+*       If the device is found on the board the then the functions returns the+*		number of those devices else the function returns 0+*+*+*******************************************************************************/+MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)+{+	MV_U32	foundIndex=0,devNum;+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");+		return 0xFFFFFFFF;++	}++	for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)+	{+		if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)+		{+			foundIndex++;+		}+	}++    return foundIndex;++}++/*******************************************************************************+* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board+*+* DESCRIPTION:+*+* INPUT:+*       devIndex - The device sequential number on the board+*		devType - The device type ( Flash,RTC , etc .. )+*+* OUTPUT:+*       None.+*+* RETURN:+*       If the device is found on the board the then the functions returns the+*		Base address else the function returns 0xffffffff+*+*+*******************************************************************************/+MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)+{+	MV_DEV_CS_INFO* devEntry;+	devEntry = boardGetDevEntry(devNum,devClass);+	if (devEntry != NULL)+	{+		return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));++	}++	return 0xFFFFFFFF;+}++/*******************************************************************************+* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board+*+* DESCRIPTION:+*+* INPUT:+*       devIndex - The device sequential number on the board+*		devType - The device type ( Flash,RTC , etc .. )+*+* OUTPUT:+*       None.+*+* RETURN:+*       If the device is found on the board the then the functions returns the+*		Bus width else the function returns 0xffffffff+*+*+*******************************************************************************/+MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)+{+	MV_DEV_CS_INFO* devEntry;++	devEntry = boardGetDevEntry(devNum,devClass);+	if (devEntry != NULL)+	{+		return 8; +	}++	return 0xFFFFFFFF;++}++/*******************************************************************************+* mvBoardGetDeviceWidth - Get dev width of a device existing on the board+*+* DESCRIPTION:+*+* INPUT:+*       devIndex - The device sequential number on the board+*		devType - The device type ( Flash,RTC , etc .. )+*+* OUTPUT:+*       None.+*+* RETURN:+*       If the device is found on the board the then the functions returns the+*		dev width else the function returns 0xffffffff+*+*+*******************************************************************************/+MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)+{+	MV_DEV_CS_INFO* devEntry;+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("Board unknown.\n");+		return 0xFFFFFFFF;+	}++	devEntry = boardGetDevEntry(devNum,devClass);+	if (devEntry != NULL)+		return devEntry->devWidth;++	return MV_ERROR;++}++/*******************************************************************************+* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board+*+* DESCRIPTION:+*+* INPUT:+*       devIndex - The device sequential number on the board+*		devType - The device type ( Flash,RTC , etc .. )+*+* OUTPUT:+*       None.+*+* RETURN:+*       If the device is found on the board the then the functions returns the+*		window size else the function returns 0xffffffff+*+*+*******************************************************************************/+MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)+{+	MV_DEV_CS_INFO* devEntry;+	MV_U32 boardId = mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("Board unknown.\n");+		return 0xFFFFFFFF;+	}++	devEntry = boardGetDevEntry(devNum,devClass);+	if (devEntry != NULL)+	{+		return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));+	}++	return 0xFFFFFFFF;+}+++/*******************************************************************************+* boardGetDevEntry - returns the entry pointer of a device on the board+*+* DESCRIPTION:+*+* INPUT:+*       devIndex - The device sequential number on the board+*		devType - The device type ( Flash,RTC , etc .. )+*+* OUTPUT:+*       None.+*+* RETURN:+*       If the device is found on the board the then the functions returns the+*		dev number else the function returns 0x0+*+*+*******************************************************************************/+static MV_DEV_CS_INFO*  boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)+{+	MV_U32	foundIndex=0,devIndex;+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("boardGetDevEntry: Board unknown.\n");+		return NULL;++	}++	for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)+	{+		/* TBR */+		/*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)+		     continue;*/++		if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)+		{+            		if (foundIndex == devNum)+			{+				return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);+			}+			foundIndex++;+		}+	}++	/* device not found */+	return NULL;+}++/* Get device CS number */++MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)+{+	MV_DEV_CS_INFO* devEntry;+	MV_U32 boardId= mvBoardIdGet();++	if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))+	{+		mvOsPrintf("Board unknown.\n");+		return 0xFFFFFFFF;++	}+++	devEntry = boardGetDevEntry(devNum,devClass);+	if (devEntry != NULL)+		return devEntry->deviceCS;++	return 0xFFFFFFFF;++}++/*******************************************************************************+* mvBoardRtcTwsiAddrTypeGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardRtcTwsiAddrTypeGet()+{+	int i;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)+			return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;+	return (MV_ERROR);+}++/*******************************************************************************+* mvBoardRtcTwsiAddrGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardRtcTwsiAddrGet()+{+	int i;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)+			return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;+	return (0xFF);+}++/*******************************************************************************+* mvBoardA2DTwsiAddrTypeGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardA2DTwsiAddrTypeGet()+{+	int i;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)+			return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;+	return (MV_ERROR);+}++/*******************************************************************************+* mvBoardA2DTwsiAddrGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardA2DTwsiAddrGet()+{+	int i;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)+			return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;+	return (0xFF);+}++/*******************************************************************************+* mvBoardTwsiExpAddrTypeGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)+{+	int i;+	MV_U32 indexFound = 0;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)+		{+			if (indexFound == index)+				return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;+			else+				indexFound++;+		}++	return (MV_ERROR);+}++/*******************************************************************************+* mvBoardTwsiExpAddrGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)+{+	int i;+	MV_U32 indexFound = 0;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)+		{+			if (indexFound == index)+				return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;+			else+				indexFound++;+		}++	return (0xFF);+}+++/*******************************************************************************+* mvBoardTwsiSatRAddrTypeGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)+{+	int i;+	MV_U32 indexFound = 0;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)+		{+			if (indexFound == index)+				return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;+			else+				indexFound++;+		}++	return (MV_ERROR);+}++/*******************************************************************************+* mvBoardTwsiSatRAddrGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)+{+	int i;+	MV_U32 indexFound = 0;+	MV_U32 boardId= mvBoardIdGet();++	for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)+		if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)+		{+			if (indexFound == index)+				return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;+			else+				indexFound++;+		}++	return (0xFF);+}++/*******************************************************************************+* mvBoardNandWidthGet -+*+* DESCRIPTION: Get the width of the first NAND device in byte.+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN: 1, 2, 4 or MV_ERROR+*+*+*******************************************************************************/+/*  */+MV_32 mvBoardNandWidthGet(void)+{+	MV_U32 devNum;+	MV_U32 devWidth;+	MV_U32 boardId= mvBoardIdGet();++	for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)+	{+		devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);+		if (devWidth != MV_ERROR)+			return (devWidth / 8);+	}+		+	/* NAND wasn't found */+	return MV_ERROR;+}++MV_U32 gBoardId = -1;++/*******************************************************************************+* mvBoardIdGet - Get Board model+*+* DESCRIPTION:+*       This function returns board ID.+*       Board ID is 32bit word constructed of board model (16bit) and+*       board revision (16bit) in the following way: 0xMMMMRRRR.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit board ID number, '-1' if board is undefined.+*+*******************************************************************************/+MV_U32 mvBoardIdGet(MV_VOID)+{+	MV_U32 tmpBoardId = -1;++	if(gBoardId == -1)+        {+		#if defined(DB_88F6281A)+		tmpBoardId = DB_88F6281A_BP_ID;+		#elif defined(RD_88F6281A)+		tmpBoardId = RD_88F6281A_ID;+		#elif defined(DB_88F6192A)+		tmpBoardId = DB_88F6192A_BP_ID;+		#elif defined(DB_88F6190A)+		tmpBoardId = DB_88F6190A_BP_ID;+		#elif defined(RD_88F6192A)+		tmpBoardId = RD_88F6192A_ID;+		#elif defined(RD_88F6190A)+		tmpBoardId = RD_88F6190A_ID;+		#elif defined(DB_88F6180A)+		tmpBoardId = DB_88F6180A_BP_ID;+		#elif defined(RD_88F6281A_PCAC)+		tmpBoardId = RD_88F6281A_PCAC_ID;+		#elif defined(RD_88F6281A_SHEEVA_PLUG)+		tmpBoardId = SHEEVA_PLUG_ID;+		#elif defined(DB_CUSTOMER)+		tmpBoardId = DB_CUSTOMER_ID;+		#endif+		gBoardId = tmpBoardId;+	}++	return gBoardId;+}+++/*******************************************************************************+* mvBoarModuleTypeGet - mvBoarModuleTypeGet+*+* DESCRIPTION:+*+* INPUT:+*		group num - MV_BOARD_MPP_GROUP_CLASS enum+*+* OUTPUT:+*		None.+*+* RETURN:+*		module num - MV_BOARD_MODULE_CLASS enum+*+*******************************************************************************/+MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)+{+    	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+    	MV_U8 data;++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++    	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: Read MPP module ID\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);+    	twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);+    	twsiSlave.validOffset = MV_TRUE;+	/* Offset is the first command after the address which indicate the register number to be read +	   in next operation */+    	twsiSlave.offset = 0;+    	twsiSlave.moreThen256 = MV_FALSE;++++    	if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )+    	{+    		DB(mvOsPrintf("Board: Read MPP module ID fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));+	+	return data;+}++/*******************************************************************************+* mvBoarTwsiSatRGet - +*+* DESCRIPTION:+*+* INPUT:+*		device num - one of three devices+*		reg num - 0 or 1+*+* OUTPUT:+*		None.+*+* RETURN:+*		reg value+*+*******************************************************************************/+MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)+{+    	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+    	MV_U8 data;++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++    	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: Read S@R device read\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);+    	twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);+    	twsiSlave.validOffset = MV_TRUE;+	/* Use offset as command */+    	twsiSlave.offset = regNum;+    	twsiSlave.moreThen256 = MV_FALSE;++    	if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )+    	{+    		DB(mvOsPrintf("Board: Read S@R fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: Read S@R succeded\n"));+	+	return data;+}++/*******************************************************************************+* mvBoarTwsiSatRSet - +*+* DESCRIPTION:+*+* INPUT:+*		devNum - one of three devices+*		regNum - 0 or 1+*		regVal - value+*+*+* OUTPUT:+*		None.+*+* RETURN:+*		reg value+*+*******************************************************************************/+MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)+{+    	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+	+	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++    	/* Read MPP module ID */+    	twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);+    	twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);+    	twsiSlave.validOffset = MV_TRUE;+    	DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\+								twsiSlave.slaveAddr.type, regVal));+	/* Use offset as command */+    	twsiSlave.offset = regNum;+    	twsiSlave.moreThen256 = MV_FALSE;+    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, ®Val, 1) )+    	{+    		DB(mvOsPrintf("Board: Write S@R fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: Write S@R succeded\n"));+	+	return MV_OK;+}++/*******************************************************************************+* mvBoardSlicGpioPinGet -+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*+*******************************************************************************/+MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)+{+	MV_U32 boardId;+	boardId = mvBoardIdGet();++	switch (boardId)+	{+	case DB_88F6281A_BP_ID:+	case RD_88F6281A_ID:+	default:+		return MV_ERROR;+		break;++	}+}++/*******************************************************************************+* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A+*+* DESCRIPTION:+*+* INPUT:+*        mode - MV_TRUE = on ; MV_FALSE = off+*+* OUTPUT:+*       MV_STATUS - MV_OK , MV_ERROR.+*+* RETURN:+*+*******************************************************************************/+MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)+{++	MV_U8 val = 1, twsiVal;+   	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+	+	if(mvBoardIdGet() != RD_88F6281A_ID)+        return MV_ERROR;++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: twsi exp set\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);+    	twsiSlave.slaveAddr.type = ADDR7_BIT;+    	twsiSlave.validOffset = MV_TRUE;+	/* Offset is the first command after the address which indicate the register number to be read +	   in next operation */+    	twsiSlave.offset = 3;+    	twsiSlave.moreThen256 = MV_FALSE;+        if(mode == MV_TRUE)+            val = 0x1;+        else+            val = 0;+        mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        val = (twsiVal & 0xfe) | val;++        if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp out val fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));+    	+	/* Change twsi exp to output */+    	twsiSlave.offset = 7;+        mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        val = (twsiVal & 0xfe);+    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp change to out fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));+        return MV_OK;+}++/*******************************************************************************+* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A+*+* DESCRIPTION:+*+* INPUT:+*        mode - MV_TRUE = on ; MV_FALSE = off+*+* OUTPUT:+*       MV_STATUS - MV_OK , MV_ERROR.+*+* RETURN:+*+*******************************************************************************/+MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)+{++	MV_U8 val = 1, twsiVal;+   	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+	+	if(mvBoardIdGet() != RD_88F6281A_ID)+        return MV_ERROR;++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: twsi exp set\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);+    	twsiSlave.slaveAddr.type = ADDR7_BIT;+    	twsiSlave.validOffset = MV_TRUE;+	/* Offset is the first command after the address which indicate the register number to be read +	   in next operation */+    	twsiSlave.offset = 3;+    	twsiSlave.moreThen256 = MV_FALSE;+        if(mode == MV_TRUE)+            val = 0x2;+        else+            val = 0;+        mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        val = (twsiVal & 0xfd) | val;+    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp out val fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));+    	+	/* Change twsi exp to output */+    	twsiSlave.offset = 7;+        mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        val = (twsiVal & 0xfd);+    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp change to out fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));+        return MV_OK;+}++/*******************************************************************************+* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A+*+* DESCRIPTION:+*+* INPUT:+*        mode - MV_TRUE = on ; MV_FALSE = off+*+* OUTPUT:+*       MV_STATUS - MV_OK , MV_ERROR.+*+* RETURN:+*+*******************************************************************************/+MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)+{++	MV_U8 val = 1, twsiVal;+   	MV_TWSI_SLAVE twsiSlave;+	MV_TWSI_ADDR slave;+	+	if(mvBoardIdGet() != RD_88F6281A_ID)+        return MV_ERROR;++	/* TWSI init */    	+	slave.type = ADDR7_BIT;+	slave.address = 0;+	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);++	/* Read MPP module ID */+    	DB(mvOsPrintf("Board: twsi exp set\n"));+    	twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);+    	twsiSlave.slaveAddr.type = ADDR7_BIT;+    	twsiSlave.validOffset = MV_TRUE;+	/* Offset is the first command after the address which indicate the register number to be read +	   in next operation */+    	twsiSlave.offset = 3;+    	twsiSlave.moreThen256 = MV_FALSE;+        if(mode == MV_TRUE)+            val = 0x10;+        else+            val = 0;+        mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        val = (twsiVal & 0xef) | val;+    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp out val fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: twsi exp out val succeded\n"));+    	+	/* Change twsi exp to output */+    	twsiSlave.offset = 7;+        mvTwsiRead(0, &twsiSlave, &twsiVal, 1);+        val = (twsiVal & 0xef);+    	if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )+    	{+    		DB(mvOsPrintf("Board: twsi exp change to out fail\n"));+        	return MV_ERROR;+    	}+    	DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));+        return MV_OK;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h	2010-11-09 20:28:07.362495449 +0100@@ -0,0 +1,376 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#ifndef __INCmvBoardEnvLibh+#define __INCmvBoardEnvLibh++/* defines */+/* The below constant macros defines the board I2C EEPROM data offsets */++++#include "ctrlEnv/mvCtrlEnvLib.h"+#include "mvSysHwConfig.h"+#include "boardEnv/mvBoardEnvSpec.h"+++/* DUART stuff for Tclk detection only */+#define DUART_BAUD_RATE			115200+#define MAX_CLOCK_MARGINE		5000000	/* Maximum detected clock margine */++/* Voice devices assembly modes */+#define DAISY_CHAIN_MODE	1+#define DUAL_CHIP_SELECT_MODE   0+#define INTERRUPT_TO_MPP        1+#define INTERRUPT_TO_TDM	0+++#define BOARD_ETH_PORT_NUM  MV_ETH_MAX_PORTS+#define BOARD_ETH_SWITCH_PORT_NUM	5++#define	MV_BOARD_MAX_USB_IF		1+#define MV_BOARD_MAX_MPP		7+#define MV_BOARD_NAME_LEN  		0x20++typedef struct _boardData+{+   MV_U32 magic;+   MV_U16 boardId;+   MV_U8 boardVer;+   MV_U8 boardRev;+   MV_U32 reserved1;+   MV_U32 reserved2;++}BOARD_DATA;++typedef enum _devBoardMppGroupClass+{+	MV_BOARD_MPP_GROUP_1,+	MV_BOARD_MPP_GROUP_2,+	MV_BOARD_MAX_MPP_GROUP+}MV_BOARD_MPP_GROUP_CLASS;++typedef enum _devBoardMppTypeClass+{+	MV_BOARD_AUTO,+	MV_BOARD_TDM,+	MV_BOARD_AUDIO,+	MV_BOARD_RGMII,+	MV_BOARD_GMII,+	MV_BOARD_TS,+	MV_BOARD_MII,+	MV_BOARD_OTHER+}MV_BOARD_MPP_TYPE_CLASS;++typedef enum _devBoardModuleIdClass+{+	MV_BOARD_MODULE_TDM_ID = 1,+	MV_BOARD_MODULE_AUDIO_ID,+	MV_BOARD_MODULE_RGMII_ID,+	MV_BOARD_MODULE_GMII_ID,+	MV_BOARD_MODULE_TS_ID,+	MV_BOARD_MODULE_MII_ID,+	MV_BOARD_MODULE_TDM_5CHAN_ID,+	MV_BOARD_MODULE_OTHER_ID+}MV_BOARD_MODULE_ID_CLASS;++typedef struct _boardMppTypeInfo+{+	MV_BOARD_MPP_TYPE_CLASS	boardMppGroup1;+	MV_BOARD_MPP_TYPE_CLASS	boardMppGroup2;++}MV_BOARD_MPP_TYPE_INFO;+++typedef enum _devBoardClass+{+	BOARD_DEV_NOR_FLASH,+	BOARD_DEV_NAND_FLASH,+	BOARD_DEV_SEVEN_SEG,+	BOARD_DEV_FPGA,+	BOARD_DEV_SRAM,+	BOARD_DEV_SPI_FLASH,+	BOARD_DEV_OTHER,+}MV_BOARD_DEV_CLASS;++typedef enum _devTwsiBoardClass+{+	BOARD_TWSI_RTC,+	BOARD_DEV_TWSI_EXP,+	BOARD_DEV_TWSI_SATR,+	BOARD_TWSI_AUDIO_DEC,+	BOARD_TWSI_OTHER+}MV_BOARD_TWSI_CLASS;+	+typedef enum _devGppBoardClass+{+	BOARD_GPP_RTC,+	BOARD_GPP_MV_SWITCH,+	BOARD_GPP_USB_VBUS,+	BOARD_GPP_USB_VBUS_EN,+	BOARD_GPP_USB_OC,+	BOARD_GPP_USB_HOST_DEVICE,+	BOARD_GPP_REF_CLCK,+	BOARD_GPP_VOIP_SLIC,+	BOARD_GPP_LIFELINE,+	BOARD_GPP_BUTTON,+	BOARD_GPP_TS_BUTTON_C,+	BOARD_GPP_TS_BUTTON_U,+	BOARD_GPP_TS_BUTTON_D,+	BOARD_GPP_TS_BUTTON_L,+	BOARD_GPP_TS_BUTTON_R,+	BOARD_GPP_POWER_BUTTON,+	BOARD_GPP_RESTOR_BUTTON,+	BOARD_GPP_WPS_BUTTON,+	BOARD_GPP_HDD0_POWER,+	BOARD_GPP_HDD1_POWER,+	BOARD_GPP_FAN_POWER,+	BOARD_GPP_RESET,+	BOARD_GPP_POWER_ON_LED,+	BOARD_GPP_HDD_POWER,+    BOARD_GPP_SDIO_POWER,+    BOARD_GPP_SDIO_DETECT,+    BOARD_GPP_SDIO_WP,+	BOARD_GPP_SWITCH_PHY_INT,+	BOARD_GPP_TSU_DIRCTION,+	BOARD_GPP_OTHER+}MV_BOARD_GPP_CLASS;+++typedef struct _devCsInfo+{+    MV_U8		deviceCS;+    MV_U32		params;+    MV_U32		devClass;	/* MV_BOARD_DEV_CLASS */+    MV_U8		devWidth;++}MV_DEV_CS_INFO;+++#define MV_BOARD_PHY_FORCE_10MB		0x0+#define MV_BOARD_PHY_FORCE_100MB	0x1+#define MV_BOARD_PHY_FORCE_1000MB	0x2+#define MV_BOARD_PHY_SPEED_AUTO		0x3++typedef struct _boardSwitchInfo+{+	MV_32	linkStatusIrq;+	MV_32	qdPort[BOARD_ETH_SWITCH_PORT_NUM];+	MV_32	qdCpuPort;+	MV_32	smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */+	MV_32	switchOnPort;++}MV_BOARD_SWITCH_INFO;++typedef struct _boardLedInfo+{+	MV_U8	activeLedsNumber;+	MV_U8	ledsPolarity;	/* '0' or '1' to turn on led */+	MV_U8*	gppPinNum; 	/* Pointer to GPP values */++}MV_BOARD_LED_INFO;++typedef struct _boardGppInfo+{+	MV_BOARD_GPP_CLASS	devClass;+	MV_U8	gppPinNum;++}MV_BOARD_GPP_INFO;+++typedef struct _boardTwsiInfo+{+	MV_BOARD_TWSI_CLASS	devClass;+	MV_U8	twsiDevAddr;+	MV_U8	twsiDevAddrType;++}MV_BOARD_TWSI_INFO;+++typedef enum _boardMacSpeed+{+	BOARD_MAC_SPEED_10M,+	BOARD_MAC_SPEED_100M,+	BOARD_MAC_SPEED_1000M,+	BOARD_MAC_SPEED_AUTO,++}MV_BOARD_MAC_SPEED;++typedef struct _boardMacInfo+{+	MV_BOARD_MAC_SPEED	boardMacSpeed;+	MV_U8	boardEthSmiAddr;++}MV_BOARD_MAC_INFO;++typedef struct _boardMppInfo+{+	MV_U32		mppGroup[MV_BOARD_MAX_MPP];++}MV_BOARD_MPP_INFO;++typedef struct _boardInfo+{+	char 			   	boardName[MV_BOARD_NAME_LEN];+	MV_U8				numBoardMppTypeValue;+	MV_BOARD_MPP_TYPE_INFO*		pBoardMppTypeValue;+	MV_U8				numBoardMppConfigValue;+	MV_BOARD_MPP_INFO*		pBoardMppConfigValue;+    	MV_U32				intsGppMaskLow;+	MV_U32				intsGppMaskHigh;+	MV_U8				numBoardDeviceIf;+    	MV_DEV_CS_INFO*			pDevCsInfo;+	MV_U8				numBoardTwsiDev;+	MV_BOARD_TWSI_INFO*		pBoardTwsiDev;+	MV_U8				numBoardMacInfo;+	MV_BOARD_MAC_INFO*		pBoardMacInfo;+	MV_U8				numBoardGppInfo;+	MV_BOARD_GPP_INFO*		pBoardGppInfo;+    	MV_U8				activeLedsNumber;+	MV_U8*				pLedGppPin;+	MV_U8				ledsPolarity;	/* '0' or '1' to turn on led */+	/* GPP values */+	MV_U32				gppOutEnValLow;+	MV_U32				gppOutEnValHigh;+	MV_U32				gppOutValLow;+	MV_U32				gppOutValHigh;+	MV_U32				gppPolarityValLow;+	MV_U32				gppPolarityValHigh;++	/* Switch Configuration */+	MV_BOARD_SWITCH_INFO*		pSwitchInfo;+}MV_BOARD_INFO;++++MV_VOID 	mvBoardEnvInit(MV_VOID);+MV_U32      	mvBoardIdGet(MV_VOID);+MV_U16      	mvBoardModelGet(MV_VOID);+MV_U16      	mvBoardRevGet(MV_VOID);+MV_STATUS	mvBoardNameGet(char *pNameBuff);+MV_32      	mvBoardPhyAddrGet(MV_U32 ethPortNum);+MV_BOARD_MAC_SPEED      mvBoardMacSpeedGet(MV_U32 ethPortNum);+MV_32		mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);+MV_32		mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);+MV_32		mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);+MV_32		mvBoardIsSwitchConnected(MV_U32 ethPortNum);+MV_32		mvBoardSmiScanModeGet(MV_U32 ethPortNum);+MV_BOOL     	mvBoardIsPortInSgmii(MV_U32 ethPortNum);+MV_BOOL 	mvBoardIsPortInGmii(MV_VOID);+MV_U32 		mvBoardTclkGet(MV_VOID);+MV_U32      	mvBoardSysClkGet(MV_VOID);+MV_U32 		mvBoardDebugLedNumGet(MV_U32 boardId);+MV_VOID     	mvBoardDebugLed(MV_U32 hexNum);+MV_32      	mvBoardMppGet(MV_U32 mppGroupNum);++MV_U8		mvBoardRtcTwsiAddrTypeGet(MV_VOID);+MV_U8		mvBoardRtcTwsiAddrGet(MV_VOID);++MV_U8		mvBoardA2DTwsiAddrTypeGet(MV_VOID);+MV_U8		mvBoardA2DTwsiAddrGet(MV_VOID);++MV_U8 		mvBoardTwsiExpAddrGet(MV_U32 index);+MV_U8 		mvBoardTwsiSatRAddrTypeGet(MV_U32 index);+MV_U8 		mvBoardTwsiSatRAddrGet(MV_U32 index);+MV_U8 		mvBoardTwsiExpAddrTypeGet(MV_U32 index);+MV_BOARD_MODULE_ID_CLASS 	mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);+MV_BOARD_MPP_TYPE_CLASS 	mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);+MV_VOID 	mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,+						MV_BOARD_MPP_TYPE_CLASS mppGroupType);+MV_VOID 	mvBoardMppGroupIdUpdate(MV_VOID);+MV_VOID 	mvBoardMppMuxSet(MV_VOID);+MV_VOID 	mvBoardTdmMppSet(MV_32 chType);+MV_VOID 	mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);++MV_VOID 	mvBoardMppModuleTypePrint(MV_VOID);+MV_VOID	    	mvBoardReset(MV_VOID);+MV_U8 		mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);+MV_STATUS 		mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);+MV_BOOL 	mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);+/* Board devices API managments */+MV_32  	    mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);+MV_32  	    mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);+MV_32	    mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);+MV_32  	    mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);+MV_32  	    mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);+MV_U32 	    boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);++/* Gpio Pin Connections API */+MV_32 	    mvBoardUSBVbusGpioPinGet(int devId);+MV_32 	    mvBoardUSBVbusEnGpioPinGet(int devId);+MV_U32      mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);++MV_32	    mvBoardResetGpioPinGet(MV_VOID);+MV_32 	    mvBoardRTCGpioPinGet(MV_VOID);+MV_32 	    mvBoardGpioIntMaskLowGet(MV_VOID);+MV_32 	    mvBoardGpioIntMaskHighGet(MV_VOID);+MV_32 	    mvBoardSlicGpioPinGet(MV_U32 slicNum);++MV_32	    mvBoardSDIOGpioPinGet(MV_VOID);+MV_STATUS   mvBoardSDioWPControl(MV_BOOL mode);+MV_32	    mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);++MV_32 	    mvBoardNandWidthGet(void);+MV_STATUS   mvBoardFanPowerControl(MV_BOOL mode);+MV_STATUS   mvBoardHDDPowerControl(MV_BOOL mode);+#endif /* __INCmvBoardEnvLibh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c	2010-11-09 20:28:07.443751783 +0100@@ -0,0 +1,848 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#include "mvCommon.h"+#include "mvBoardEnvLib.h"+#include "mvBoardEnvSpec.h"+#include "twsi/mvTwsi.h"++#define DB_88F6281A_BOARD_PCI_IF_NUM            0x0+#define DB_88F6281A_BOARD_TWSI_DEF_NUM		    0x7+#define DB_88F6281A_BOARD_MAC_INFO_NUM		    0x2+#define DB_88F6281A_BOARD_GPP_INFO_NUM		    0x3+#define DB_88F6281A_BOARD_MPP_CONFIG_NUM		0x1+#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM	0x1+#if defined(MV_NAND) && defined(MV_NAND_BOOT)+    #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM	    0x1+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+    #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM	    0x2+#else+    #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM	    0x1+#endif+#define DB_88F6281A_BOARD_DEBUG_LED_NUM		    0x0+++MV_BOARD_TWSI_INFO	db88f6281AInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{+	{BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},+	{BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},+	{BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},+	{BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}+	};++MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] = +	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */+	{+	{BOARD_MAC_SPEED_AUTO, 0x8},+	{BOARD_MAC_SPEED_AUTO, 0x9}+	}; ++MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] = +	/* {{MV_BOARD_MPP_TYPE_CLASS	boardMppGroup1,+ 		MV_BOARD_MPP_TYPE_CLASS	boardMppGroup2}} */+	{{MV_BOARD_AUTO, MV_BOARD_AUTO}+	}; ++MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] = +	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */+	{+	{BOARD_GPP_TSU_DIRCTION, 33}+	/*muxed with TDM/Audio module via IOexpender+	{BOARD_GPP_SDIO_DETECT, 38},+	{BOARD_GPP_USB_VBUS, 49}*/+	};++MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +#if defined(MV_NAND) && defined(MV_NAND_BOOT)+		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */         +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+		 {+         {0, N_A, BOARD_DEV_NAND_FLASH, 8},	   /* NAND DEV */+         {1, N_A, BOARD_DEV_SPI_FLASH, 8},	   /* SPI DEV */+         };+#else+	 {{1, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */         +#endif++MV_BOARD_MPP_INFO	db88f6281AInfoBoardMppConfigValue[] = +	{{{+	DB_88F6281A_MPP0_7,		+	DB_88F6281A_MPP8_15,		+	DB_88F6281A_MPP16_23,		+	DB_88F6281A_MPP24_31,		+	DB_88F6281A_MPP32_39,		+	DB_88F6281A_MPP40_47,		+	DB_88F6281A_MPP48_55		+	}}};+++MV_BOARD_INFO db88f6281AInfo = {+	"DB-88F6281A-BP",				/* boardName[MAX_BOARD_NAME_LEN] */+	DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	db88f6281AInfoBoardMppTypeInfo,+	DB_88F6281A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	db88f6281AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	0,						/* intsGppMaskHigh */+	DB_88F6281A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	db88f6281AInfoBoardDeCsInfo,+	DB_88F6281A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	db88f6281AInfoBoardTwsiDev,					+	DB_88F6281A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	db88f6281AInfoBoardMacInfo,+	DB_88F6281A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	db88f6281AInfoBoardGppInfo,+	DB_88F6281A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	NULL,+	0,						/* ledsPolarity */		+	DB_88F6281A_OE_LOW,				/* gppOutEnLow */+	DB_88F6281A_OE_HIGH,				/* gppOutEnHigh */+	DB_88F6281A_OE_VAL_LOW,				/* gppOutValLow */+	DB_88F6281A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	BIT6, 						/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};+++#define RD_88F6281A_BOARD_PCI_IF_NUM		0x0+#define RD_88F6281A_BOARD_TWSI_DEF_NUM		0x2+#define RD_88F6281A_BOARD_MAC_INFO_NUM		0x2+#define RD_88F6281A_BOARD_GPP_INFO_NUM		0x5+#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM	0x1+#define RD_88F6281A_BOARD_MPP_CONFIG_NUM		0x1+#if defined(MV_NAND) && defined(MV_NAND_BOOT)+    #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM	    0x1+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+    #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM	    0x2+#else+    #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM	    0x1+#endif+#define RD_88F6281A_BOARD_DEBUG_LED_NUM		0x0++MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] = +	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */+	{{BOARD_MAC_SPEED_1000M, 0xa},+    {BOARD_MAC_SPEED_AUTO, 0xb}+	}; ++MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] = +	/* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4}, +		MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */+	{{38, {0, 1, 2, 3, -1}, 5, 2, 0},+	 {-1, {-1}, -1, -1, -1}};++MV_BOARD_TWSI_INFO	rd88f6281AInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{+	{BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */+	{BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}+	};++MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] = +	{{MV_BOARD_RGMII, MV_BOARD_TDM}+	}; ++MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +#if defined(MV_NAND) && defined(MV_NAND_BOOT)+		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+		 {+         {0, N_A, BOARD_DEV_NAND_FLASH, 8},	   /* NAND DEV */+         {1, N_A, BOARD_DEV_SPI_FLASH, 8},	   /* SPI DEV */+         };+#else+		 {{1, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */         +#endif++MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] = +	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */+	{{BOARD_GPP_SDIO_DETECT, 28},+    {BOARD_GPP_USB_OC, 29},+    {BOARD_GPP_WPS_BUTTON, 35},+    {BOARD_GPP_MV_SWITCH, 38},+    {BOARD_GPP_USB_VBUS, 49}+	};++MV_BOARD_MPP_INFO	rd88f6281AInfoBoardMppConfigValue[] = +	{{{+	RD_88F6281A_MPP0_7,		+	RD_88F6281A_MPP8_15,		+	RD_88F6281A_MPP16_23,		+	RD_88F6281A_MPP24_31,		+	RD_88F6281A_MPP32_39,		+	RD_88F6281A_MPP40_47,		+	RD_88F6281A_MPP48_55		+	}}};++MV_BOARD_INFO rd88f6281AInfo = {+	"RD-88F6281A",				/* boardName[MAX_BOARD_NAME_LEN] */+	RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	rd88f6281AInfoBoardMppTypeInfo,+	RD_88F6281A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	rd88f6281AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	(1 << 3),					/* intsGppMaskHigh */+	RD_88F6281A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	rd88f6281AInfoBoardDeCsInfo,+	RD_88F6281A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	rd88f6281AInfoBoardTwsiDev,					+	RD_88F6281A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	rd88f6281AInfoBoardMacInfo,+	RD_88F6281A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	rd88f6281AInfoBoardGppInfo,+	RD_88F6281A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	NULL,+	0,										/* ledsPolarity */		+	RD_88F6281A_OE_LOW,				/* gppOutEnLow */+	RD_88F6281A_OE_HIGH,				/* gppOutEnHigh */+	RD_88F6281A_OE_VAL_LOW,				/* gppOutValLow */+	RD_88F6281A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	BIT6, 						/* gppPolarityValHigh */+	rd88f6281AInfoBoardSwitchInfo			/* pSwitchInfo */+};+++#define DB_88F6192A_BOARD_PCI_IF_NUM            0x0+#define DB_88F6192A_BOARD_TWSI_DEF_NUM		    0x7+#define DB_88F6192A_BOARD_MAC_INFO_NUM		    0x2+#define DB_88F6192A_BOARD_GPP_INFO_NUM		    0x3+#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM	0x1+#define DB_88F6192A_BOARD_MPP_CONFIG_NUM		0x1+#if defined(MV_NAND) && defined(MV_NAND_BOOT)+    #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM	    0x1+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+    #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM	    0x2+#else+    #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM	    0x1+#endif+#define DB_88F6192A_BOARD_DEBUG_LED_NUM		    0x0++MV_BOARD_TWSI_INFO	db88f6192AInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{+	{BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},+	{BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},+	{BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},+	{BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}+	};++MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] = +	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */+	{+	{BOARD_MAC_SPEED_AUTO, 0x8},+	{BOARD_MAC_SPEED_AUTO, 0x9}+	}; ++MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] = +	/* {{MV_BOARD_MPP_TYPE_CLASS	boardMppGroup1,+ 		MV_BOARD_MPP_TYPE_CLASS	boardMppGroup2}} */+	{{MV_BOARD_AUTO, MV_BOARD_OTHER}+	}; ++MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +#if defined(MV_NAND) && defined(MV_NAND_BOOT)+		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+		 {+         {0, N_A, BOARD_DEV_NAND_FLASH, 8},	   /* NAND DEV */+         {1, N_A, BOARD_DEV_SPI_FLASH, 8},	   /* SPI DEV */+         };+#else+		 {{1, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */         +#endif++MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] = +	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */+	{+    {BOARD_GPP_SDIO_WP, 20},+	{BOARD_GPP_USB_VBUS, 22},+	{BOARD_GPP_SDIO_DETECT, 23},+	};++MV_BOARD_MPP_INFO	db88f6192AInfoBoardMppConfigValue[] = +	{{{+	DB_88F6192A_MPP0_7,		+	DB_88F6192A_MPP8_15,		+	DB_88F6192A_MPP16_23,		+	DB_88F6192A_MPP24_31,		+	DB_88F6192A_MPP32_35+	}}};++MV_BOARD_INFO db88f6192AInfo = {+	"DB-88F6192A-BP",				/* boardName[MAX_BOARD_NAME_LEN] */+	DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	db88f6192AInfoBoardMppTypeInfo,+	DB_88F6192A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	db88f6192AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	(1 << 3),					/* intsGppMaskHigh */+	DB_88F6192A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	db88f6192AInfoBoardDeCsInfo,+	DB_88F6192A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	db88f6192AInfoBoardTwsiDev,					+	DB_88F6192A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	db88f6192AInfoBoardMacInfo,+	DB_88F6192A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	db88f6192AInfoBoardGppInfo,+	DB_88F6192A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	NULL,+	0,										/* ledsPolarity */		+	DB_88F6192A_OE_LOW,				/* gppOutEnLow */+	DB_88F6192A_OE_HIGH,				/* gppOutEnHigh */+	DB_88F6192A_OE_VAL_LOW,				/* gppOutValLow */+	DB_88F6192A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	0, 						/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};++#define DB_88F6190A_BOARD_MAC_INFO_NUM		0x1++MV_BOARD_INFO db88f6190AInfo = {+	"DB-88F6190A-BP",				/* boardName[MAX_BOARD_NAME_LEN] */+	DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	db88f6192AInfoBoardMppTypeInfo,+	DB_88F6192A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	db88f6192AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	(1 << 3),					/* intsGppMaskHigh */+	DB_88F6192A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	db88f6192AInfoBoardDeCsInfo,+	DB_88F6192A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	db88f6192AInfoBoardTwsiDev,					+	DB_88F6190A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	db88f6192AInfoBoardMacInfo,+	DB_88F6192A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	db88f6192AInfoBoardGppInfo,+	DB_88F6192A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	NULL,+	0,										/* ledsPolarity */		+	DB_88F6192A_OE_LOW,				/* gppOutEnLow */+	DB_88F6192A_OE_HIGH,				/* gppOutEnHigh */+	DB_88F6192A_OE_VAL_LOW,				/* gppOutValLow */+	DB_88F6192A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	0, 						/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};++#define RD_88F6192A_BOARD_PCI_IF_NUM		0x0+#define RD_88F6192A_BOARD_TWSI_DEF_NUM		0x0+#define RD_88F6192A_BOARD_MAC_INFO_NUM		0x1+#define RD_88F6192A_BOARD_GPP_INFO_NUM		0xE+#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM	0x1+#define RD_88F6192A_BOARD_MPP_CONFIG_NUM		0x1+#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM	0x1+#define RD_88F6192A_BOARD_DEBUG_LED_NUM		0x3++MV_U8	rd88f6192AInfoBoardDebugLedIf[] =+	{17, 28, 29};++MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] = +	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */+	{{BOARD_MAC_SPEED_AUTO, 0x8}+	}; ++MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] = +	/* {{MV_BOARD_MPP_TYPE_CLASS	boardMppGroup1,+ 		MV_BOARD_MPP_TYPE_CLASS	boardMppGroup2}} */+	{{MV_BOARD_OTHER, MV_BOARD_OTHER}+	}; ++MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +		 {{1, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */++MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] = +	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */+	{+	{BOARD_GPP_USB_VBUS_EN, 10},+	{BOARD_GPP_USB_HOST_DEVICE, 11},+	{BOARD_GPP_RESET, 14},+	{BOARD_GPP_POWER_ON_LED, 15},+	{BOARD_GPP_HDD_POWER, 16},+	{BOARD_GPP_WPS_BUTTON, 24},+	{BOARD_GPP_TS_BUTTON_C, 25},+	{BOARD_GPP_USB_VBUS, 26},+	{BOARD_GPP_USB_OC, 27},+	{BOARD_GPP_TS_BUTTON_U, 30},+	{BOARD_GPP_TS_BUTTON_R, 31},+	{BOARD_GPP_TS_BUTTON_L, 32},+	{BOARD_GPP_TS_BUTTON_D, 34},+	{BOARD_GPP_FAN_POWER, 35}+	};++MV_BOARD_MPP_INFO	rd88f6192AInfoBoardMppConfigValue[] = +	{{{+	RD_88F6192A_MPP0_7,		+	RD_88F6192A_MPP8_15,		+	RD_88F6192A_MPP16_23,		+	RD_88F6192A_MPP24_31,		+	RD_88F6192A_MPP32_35+	}}};++MV_BOARD_INFO rd88f6192AInfo = {+	"RD-88F6192A-NAS",				/* boardName[MAX_BOARD_NAME_LEN] */+	RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	rd88f6192AInfoBoardMppTypeInfo,+	RD_88F6192A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	rd88f6192AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	(1 << 3),					/* intsGppMaskHigh */+	RD_88F6192A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	rd88f6192AInfoBoardDeCsInfo,+	RD_88F6192A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	NULL,					+	RD_88F6192A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	rd88f6192AInfoBoardMacInfo,+	RD_88F6192A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	rd88f6192AInfoBoardGppInfo,+	RD_88F6192A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	rd88f6192AInfoBoardDebugLedIf,+	0,										/* ledsPolarity */		+	RD_88F6192A_OE_LOW,				/* gppOutEnLow */+	RD_88F6192A_OE_HIGH,				/* gppOutEnHigh */+	RD_88F6192A_OE_VAL_LOW,				/* gppOutValLow */+	RD_88F6192A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	0, 						/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};++MV_BOARD_INFO rd88f6190AInfo = {+	"RD-88F6190A-NAS",				/* boardName[MAX_BOARD_NAME_LEN] */+	RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	rd88f6192AInfoBoardMppTypeInfo,+	RD_88F6192A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	rd88f6192AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	(1 << 3),					/* intsGppMaskHigh */+	RD_88F6192A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	rd88f6192AInfoBoardDeCsInfo,+	RD_88F6192A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	NULL,					+	RD_88F6192A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	rd88f6192AInfoBoardMacInfo,+	RD_88F6192A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	rd88f6192AInfoBoardGppInfo,+	RD_88F6192A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	rd88f6192AInfoBoardDebugLedIf,+	0,										/* ledsPolarity */		+	RD_88F6192A_OE_LOW,				/* gppOutEnLow */+	RD_88F6192A_OE_HIGH,				/* gppOutEnHigh */+	RD_88F6192A_OE_VAL_LOW,				/* gppOutValLow */+	RD_88F6192A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	0, 						/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};++#define DB_88F6180A_BOARD_PCI_IF_NUM		0x0+#define DB_88F6180A_BOARD_TWSI_DEF_NUM		0x5+#define DB_88F6180A_BOARD_MAC_INFO_NUM		0x1+#define DB_88F6180A_BOARD_GPP_INFO_NUM		0x0+#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM	0x2+#define DB_88F6180A_BOARD_MPP_CONFIG_NUM		0x1+#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM	    0x1+#define DB_88F6180A_BOARD_DEBUG_LED_NUM		0x0++MV_BOARD_TWSI_INFO	db88f6180AInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{+    {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},+    {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},+    {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},+	{BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},+	{BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}+	};++MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] = +	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */+	{{BOARD_MAC_SPEED_AUTO, 0x8}+	}; ++MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] = +	/* {{MV_BOARD_GPP_CLASS	devClass, MV_U8	gppPinNum}} */+	{+	/* Muxed with TDM/Audio module via IOexpender+	{BOARD_GPP_USB_VBUS, 6} */+	};++MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] = +	/* {{MV_BOARD_MPP_TYPE_CLASS	boardMppGroup1,+ 		MV_BOARD_MPP_TYPE_CLASS	boardMppGroup2}} */+	{{MV_BOARD_OTHER, MV_BOARD_AUTO}+	}; ++MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +#if defined(MV_NAND_BOOT)+		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */         +#else+		 {{1, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */         +#endif++MV_BOARD_MPP_INFO	db88f6180AInfoBoardMppConfigValue[] = +	{{{+	DB_88F6180A_MPP0_7,		+	DB_88F6180A_MPP8_15,+    DB_88F6180A_MPP16_23,+    DB_88F6180A_MPP24_31,		+    DB_88F6180A_MPP32_39,+    DB_88F6180A_MPP40_44+	}}};++MV_BOARD_INFO db88f6180AInfo = {+	"DB-88F6180A-BP",				/* boardName[MAX_BOARD_NAME_LEN] */+	DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM,		/* numBoardMppGroupType */+	db88f6180AInfoBoardMppTypeInfo,+	DB_88F6180A_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	db88f6180AInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	0,					/* intsGppMaskHigh */+	DB_88F6180A_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	db88f6180AInfoBoardDeCsInfo,+	DB_88F6180A_BOARD_TWSI_DEF_NUM,			/* numBoardTwsiDev */+	db88f6180AInfoBoardTwsiDev,					+	DB_88F6180A_BOARD_MAC_INFO_NUM,			/* numBoardMacInfo */+	db88f6180AInfoBoardMacInfo,+	DB_88F6180A_BOARD_GPP_INFO_NUM,			/* numBoardGppInfo */+	NULL,+	DB_88F6180A_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	NULL,+	0,										/* ledsPolarity */		+	DB_88F6180A_OE_LOW,				/* gppOutEnLow */+	DB_88F6180A_OE_HIGH,				/* gppOutEnHigh */+	DB_88F6180A_OE_VAL_LOW,				/* gppOutValLow */+	DB_88F6180A_OE_VAL_HIGH,				/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	0, 						/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};+++#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM		0x0+#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM		0x1+#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM		0x1+#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM		0x0+#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM	0x1+#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM		0x1+#if defined(MV_NAND) && defined(MV_NAND_BOOT)+    #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM	    0x1+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+    #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM	    0x2+#else+    #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM	    0x1+#endif+#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM		0x4++MV_U8	rd88f6281APcacInfoBoardDebugLedIf[] =+	{38, 39, 40, 41};++MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] = +	/* {{MV_BOARD_MAC_SPEED	boardMacSpeed, MV_U8 boardEthSmiAddr}} */+	{{BOARD_MAC_SPEED_AUTO, 0x8}+	}; ++MV_BOARD_TWSI_INFO	rd88f6281APcacInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{+	{BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}+	};++MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] = +	{{MV_BOARD_OTHER, MV_BOARD_OTHER}+	}; ++MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +#if defined(MV_NAND) && defined(MV_NAND_BOOT)+		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+		 {+         {0, N_A, BOARD_DEV_NAND_FLASH, 8},	   /* NAND DEV */+         {1, N_A, BOARD_DEV_SPI_FLASH, 8},	   /* SPI DEV */+         };+#else+	 {{1, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */         +#endif++MV_BOARD_MPP_INFO	rd88f6281APcacInfoBoardMppConfigValue[] = +	{{{+	RD_88F6281A_PCAC_MPP0_7,		+	RD_88F6281A_PCAC_MPP8_15,		+	RD_88F6281A_PCAC_MPP16_23,		+	RD_88F6281A_PCAC_MPP24_31,		+	RD_88F6281A_PCAC_MPP32_39,		+	RD_88F6281A_PCAC_MPP40_47,		+	RD_88F6281A_PCAC_MPP48_55		+	}}};++MV_BOARD_INFO rd88f6281APcacInfo = {+	"RD-88F6281A-PCAC",				/* boardName[MAX_BOARD_NAME_LEN] */+	RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM,	/* numBoardMppGroupType */+	rd88f6281APcacInfoBoardMppTypeInfo,+	RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM,		/* numBoardMppConfig */+	rd88f6281APcacInfoBoardMppConfigValue,+	0,						/* intsGppMaskLow */+	(1 << 3),					/* intsGppMaskHigh */+	RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM,	/* numBoardDevIf */+	rd88f6281APcacInfoBoardDeCsInfo,+	RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM,		/* numBoardTwsiDev */+	rd88f6281APcacInfoBoardTwsiDev,					+	RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM,		/* numBoardMacInfo */+	rd88f6281APcacInfoBoardMacInfo,+	RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM,		/* numBoardGppInfo */+	0,+	RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM,		/* activeLedsNumber */              +	NULL,+	0,										/* ledsPolarity */		+	RD_88F6281A_PCAC_OE_LOW,			/* gppOutEnLow */+	RD_88F6281A_PCAC_OE_HIGH,			/* gppOutEnHigh */+	RD_88F6281A_PCAC_OE_VAL_LOW,			/* gppOutValLow */+	RD_88F6281A_PCAC_OE_VAL_HIGH,			/* gppOutValHigh */+	0,						/* gppPolarityValLow */+	0, 	 					/* gppPolarityValHigh */+	NULL						/* pSwitchInfo */+};+++/* 6281 Sheeva Plug*/++#define SHEEVA_PLUG_BOARD_PCI_IF_NUM		        0x0+#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM		        0x0+#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM		        0x1+#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM		        0x0+#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN        0x1+#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM		    0x1+#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM	        0x1+#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM		        0x1++MV_U8	sheevaPlugInfoBoardDebugLedIf[] =+	{49};++MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] = +    /* {{MV_BOARD_MAC_SPEED	boardMacSpeed,	MV_U8	boardEthSmiAddr}} */+	{{BOARD_MAC_SPEED_AUTO, 0x0}}; ++MV_BOARD_TWSI_INFO	sheevaPlugInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};++MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] = +	{{MV_BOARD_OTHER, MV_BOARD_OTHER}+	}; ++MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */++MV_BOARD_MPP_INFO	sheevaPlugInfoBoardMppConfigValue[] = +	{{{+	RD_SHEEVA_PLUG_MPP0_7,		+	RD_SHEEVA_PLUG_MPP8_15,		+	RD_SHEEVA_PLUG_MPP16_23,		+	RD_SHEEVA_PLUG_MPP24_31,		+	RD_SHEEVA_PLUG_MPP32_39,		+	RD_SHEEVA_PLUG_MPP40_47,		+	RD_SHEEVA_PLUG_MPP48_55		+	}}};++MV_BOARD_INFO sheevaPlugInfo = {+	"SHEEVA PLUG",				                /* boardName[MAX_BOARD_NAME_LEN] */+	SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN,		/* numBoardMppGroupType */+	sheevaPlugInfoBoardMppTypeInfo,+	SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM,		    /* numBoardMppConfig */+	sheevaPlugInfoBoardMppConfigValue,+	0,						                    /* intsGppMaskLow */+	0,					                        /* intsGppMaskHigh */+	SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	sheevaPlugInfoBoardDeCsInfo,+	SHEEVA_PLUG_BOARD_TWSI_DEF_NUM,			    /* numBoardTwsiDev */+	sheevaPlugInfoBoardTwsiDev,					+	SHEEVA_PLUG_BOARD_MAC_INFO_NUM,			    /* numBoardMacInfo */+	sheevaPlugInfoBoardMacInfo,+	SHEEVA_PLUG_BOARD_GPP_INFO_NUM,			    /* numBoardGppInfo */+	0,+	SHEEVA_PLUG_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	sheevaPlugInfoBoardDebugLedIf,+	0,										/* ledsPolarity */		+	RD_SHEEVA_PLUG_OE_LOW,				            /* gppOutEnLow */+	RD_SHEEVA_PLUG_OE_HIGH,				        /* gppOutEnHigh */+	RD_SHEEVA_PLUG_OE_VAL_LOW,				        /* gppOutValLow */+	RD_SHEEVA_PLUG_OE_VAL_HIGH,				    /* gppOutValHigh */+	0,						                    /* gppPolarityValLow */+	0, 						                    /* gppPolarityValHigh */+    NULL										/* pSwitchInfo */+};++/* Customer specific board place holder*/++#define DB_CUSTOMER_BOARD_PCI_IF_NUM		        0x0+#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM		        0x0+#define DB_CUSTOMER_BOARD_MAC_INFO_NUM		        0x0+#define DB_CUSTOMER_BOARD_GPP_INFO_NUM		        0x0+#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN        0x0+#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM		    0x0+#if defined(MV_NAND) && defined(MV_NAND_BOOT)+    #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM	    0x0+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+    #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM	    0x0+#else+    #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM	    0x0+#endif+#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM		0x0++MV_U8	dbCustomerInfoBoardDebugLedIf[] =+	{0};++MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] = +    /* {{MV_BOARD_MAC_SPEED	boardMacSpeed,	MV_U8	boardEthSmiAddr}} */+	{{BOARD_MAC_SPEED_AUTO, 0x0}}; ++MV_BOARD_TWSI_INFO	dbCustomerInfoBoardTwsiDev[] =+	/* {{MV_BOARD_DEV_CLASS	devClass, MV_U8	twsiDevAddr, MV_U8 twsiDevAddrType}} */+	{{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};++MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] = +	{{MV_BOARD_OTHER, MV_BOARD_OTHER}+	}; ++MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] = +		/*{deviceCS, params, devType, devWidth}*/			   +#if defined(MV_NAND) && defined(MV_NAND_BOOT)+		 {{0, N_A, BOARD_DEV_NAND_FLASH, 8}};	   /* NAND DEV */+#elif defined(MV_NAND) && defined(MV_SPI_BOOT)+		 {+         {0, N_A, BOARD_DEV_NAND_FLASH, 8},	   /* NAND DEV */+         {2, N_A, BOARD_DEV_SPI_FLASH, 8},	   /* SPI DEV */+         };+#else+		 {{2, N_A, BOARD_DEV_SPI_FLASH, 8}};	   /* SPI DEV */         +#endif++MV_BOARD_MPP_INFO	dbCustomerInfoBoardMppConfigValue[] = +	{{{+	DB_CUSTOMER_MPP0_7,		+	DB_CUSTOMER_MPP8_15,		+	DB_CUSTOMER_MPP16_23,		+	DB_CUSTOMER_MPP24_31,		+	DB_CUSTOMER_MPP32_39,		+	DB_CUSTOMER_MPP40_47,		+	DB_CUSTOMER_MPP48_55		+	}}};++MV_BOARD_INFO dbCustomerInfo = {+	"DB-CUSTOMER",				                /* boardName[MAX_BOARD_NAME_LEN] */+	DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN,		/* numBoardMppGroupType */+	dbCustomerInfoBoardMppTypeInfo,+	DB_CUSTOMER_BOARD_MPP_CONFIG_NUM,		    /* numBoardMppConfig */+	dbCustomerInfoBoardMppConfigValue,+	0,						                    /* intsGppMaskLow */+	0,					                        /* intsGppMaskHigh */+	DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM,		/* numBoardDevIf */+	dbCustomerInfoBoardDeCsInfo,+	DB_CUSTOMER_BOARD_TWSI_DEF_NUM,			    /* numBoardTwsiDev */+	dbCustomerInfoBoardTwsiDev,					+	DB_CUSTOMER_BOARD_MAC_INFO_NUM,			    /* numBoardMacInfo */+	dbCustomerInfoBoardMacInfo,+	DB_CUSTOMER_BOARD_GPP_INFO_NUM,			    /* numBoardGppInfo */+	0,+	DB_CUSTOMER_BOARD_DEBUG_LED_NUM,			/* activeLedsNumber */              +	NULL,+	0,										/* ledsPolarity */		+	DB_CUSTOMER_OE_LOW,				            /* gppOutEnLow */+	DB_CUSTOMER_OE_HIGH,				        /* gppOutEnHigh */+	DB_CUSTOMER_OE_VAL_LOW,				        /* gppOutValLow */+	DB_CUSTOMER_OE_VAL_HIGH,				    /* gppOutValHigh */+	0,						                    /* gppPolarityValLow */+	0, 						                    /* gppPolarityValHigh */+    NULL										/* pSwitchInfo */+};++MV_BOARD_INFO*	boardInfoTbl[] = 	{+                    &db88f6281AInfo,+                    &rd88f6281AInfo,+                    &db88f6192AInfo,+                    &rd88f6192AInfo,+                    &db88f6180AInfo,+                    &db88f6190AInfo,+                    &rd88f6190AInfo,+                    &rd88f6281APcacInfo,+                    &dbCustomerInfo,+                    &sheevaPlugInfo+					};++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h	2010-11-09 20:28:07.482495476 +0100@@ -0,0 +1,262 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvBoardEnvSpech+#define __INCmvBoardEnvSpech++#include "mvSysHwConfig.h"+++/* For future use */+#define BD_ID_DATA_START_OFFS		0x0+#define BD_DETECT_SEQ_OFFS		0x0+#define BD_SYS_NUM_OFFS			0x4+#define BD_NAME_OFFS			0x8++/* I2C bus addresses */+#define MV_BOARD_CTRL_I2C_ADDR			0x0     /* Controller slave addr */+#define MV_BOARD_CTRL_I2C_ADDR_TYPE 		ADDR7_BIT+#define MV_BOARD_DIMM0_I2C_ADDR			0x56+#define MV_BOARD_DIMM0_I2C_ADDR_TYPE 		ADDR7_BIT+#define MV_BOARD_DIMM1_I2C_ADDR			0x54+#define MV_BOARD_DIMM1_I2C_ADDR_TYPE 		ADDR7_BIT+#define MV_BOARD_EEPROM_I2C_ADDR	    	0x51+#define MV_BOARD_EEPROM_I2C_ADDR_TYPE 		ADDR7_BIT+#define MV_BOARD_MAIN_EEPROM_I2C_ADDR	   	0x50+#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE 	ADDR7_BIT+#define MV_BOARD_MUX_I2C_ADDR_ENTRY		0x2+#define MV_BOARD_DIMM_I2C_CHANNEL		0x0++#define BOOT_FLASH_INDEX			0+#define MAIN_FLASH_INDEX			1++#define BOARD_ETH_START_PORT_NUM	0++/* Supported clocks */+#define MV_BOARD_TCLK_100MHZ	100000000+#define MV_BOARD_TCLK_125MHZ	125000000+#define MV_BOARD_TCLK_133MHZ	133333333+#define MV_BOARD_TCLK_150MHZ	150000000+#define MV_BOARD_TCLK_166MHZ	166666667+#define MV_BOARD_TCLK_200MHZ	200000000++#define MV_BOARD_SYSCLK_100MHZ	100000000+#define MV_BOARD_SYSCLK_125MHZ	125000000+#define MV_BOARD_SYSCLK_133MHZ	133333333+#define MV_BOARD_SYSCLK_150MHZ	150000000+#define MV_BOARD_SYSCLK_166MHZ	166666667+#define MV_BOARD_SYSCLK_200MHZ	200000000+#define MV_BOARD_SYSCLK_233MHZ	233333333+#define MV_BOARD_SYSCLK_250MHZ	250000000+#define MV_BOARD_SYSCLK_267MHZ	266666667+#define MV_BOARD_SYSCLK_300MHZ	300000000+#define MV_BOARD_SYSCLK_333MHZ	333333334+#define MV_BOARD_SYSCLK_400MHZ	400000000++#define MV_BOARD_REFCLK_25MHZ	 25000000++/* Board specific */+/* =============================== */++/* boards ID numbers */++#define BOARD_ID_BASE           		0x0++/* New board ID numbers */+#define DB_88F6281A_BP_ID			(BOARD_ID_BASE)+#define DB_88F6281_BP_MLL_ID        1680+#define RD_88F6281A_ID				(BOARD_ID_BASE+0x1)+#define RD_88F6281_MLL_ID			1682+#define DB_88F6192A_BP_ID			(BOARD_ID_BASE+0x2)+#define RD_88F6192A_ID				(BOARD_ID_BASE+0x3)+#define RD_88F6192_MLL_ID			1681+#define DB_88F6180A_BP_ID			(BOARD_ID_BASE+0x4)+#define DB_88F6190A_BP_ID			(BOARD_ID_BASE+0x5)+#define RD_88F6190A_ID				(BOARD_ID_BASE+0x6)+#define RD_88F6281A_PCAC_ID			(BOARD_ID_BASE+0x7)+#define DB_CUSTOMER_ID			    (BOARD_ID_BASE+0x8)+#define SHEEVA_PLUG_ID			    (BOARD_ID_BASE+0x9)+#define MV_MAX_BOARD_ID 			(SHEEVA_PLUG_ID + 1)++/* DB-88F6281A-BP */+#if defined(MV_NAND)+    #define DB_88F6281A_MPP0_7                   	0x21111111+#else+    #define DB_88F6281A_MPP0_7                   	0x21112220+#endif+#define DB_88F6281A_MPP8_15                   	0x11113311+#define DB_88F6281A_MPP16_23                   	0x00551111+#define DB_88F6281A_MPP24_31                   	0x00000000+#define DB_88F6281A_MPP32_39                   	0x00000000+#define DB_88F6281A_MPP40_47                   	0x00000000+#define DB_88F6281A_MPP48_55                   	0x00000000+#define DB_88F6281A_OE_LOW                       0x0+#if defined(MV_TDM_5CHANNELS)+	#define DB_88F6281A_OE_HIGH		(BIT6)+#else+#define DB_88F6281A_OE_HIGH                      0x0+#endif+#define DB_88F6281A_OE_VAL_LOW                   0x0+#define DB_88F6281A_OE_VAL_HIGH                  0x0++/* RD-88F6281A */+#if defined(MV_NAND)+    #define RD_88F6281A_MPP0_7                   	0x21111111+#else+    #define RD_88F6281A_MPP0_7                   	0x21112220+#endif+#define RD_88F6281A_MPP8_15                   	0x11113311+#define RD_88F6281A_MPP16_23                   	0x33331111+#define RD_88F6281A_MPP24_31                   	0x33003333+#define RD_88F6281A_MPP32_39                   	0x20440533+#define RD_88F6281A_MPP40_47                   	0x22202222+#define RD_88F6281A_MPP48_55                   	0x00000002+#define RD_88F6281A_OE_LOW                      (BIT28 | BIT29)+#define RD_88F6281A_OE_HIGH                     (BIT3 | BIT6 | BIT17)+#define RD_88F6281A_OE_VAL_LOW                   0x0+#define RD_88F6281A_OE_VAL_HIGH                  0x0++/* DB-88F6192A-BP */+#if defined(MV_NAND)+    #define DB_88F6192A_MPP0_7                   	0x21111111+#else+    #define DB_88F6192A_MPP0_7                   	0x21112220+#endif+#define DB_88F6192A_MPP8_15                   	0x11113311+#define DB_88F6192A_MPP16_23                   	0x00501111+#define DB_88F6192A_MPP24_31                   	0x00000000+#define DB_88F6192A_MPP32_35                   	0x00000000+#define DB_88F6192A_OE_LOW                       (BIT22 | BIT23)+#define DB_88F6192A_OE_HIGH                      0x0+#define DB_88F6192A_OE_VAL_LOW                   0x0+#define DB_88F6192A_OE_VAL_HIGH                  0x0++/* RD-88F6192A */+#define RD_88F6192A_MPP0_7                   	0x01222222+#define RD_88F6192A_MPP8_15                   	0x00000011+#define RD_88F6192A_MPP16_23                   	0x05550000+#define RD_88F6192A_MPP24_31                   	0x0+#define RD_88F6192A_MPP32_35                   	0x0+#define RD_88F6192A_OE_LOW                      (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)+#define RD_88F6192A_OE_HIGH                     (BIT0 | BIT2)+#define RD_88F6192A_OE_VAL_LOW                  0x18400+#define RD_88F6192A_OE_VAL_HIGH                 0x8++/* DB-88F6180A-BP */+#if defined(MV_NAND)+    #define DB_88F6180A_MPP0_7                   	0x21111111+#else+    #define DB_88F6180A_MPP0_7                   	0x01112222+#endif+#define DB_88F6180A_MPP8_15                   	0x11113311+#define DB_88F6180A_MPP16_23                   	0x00001111+#define DB_88F6180A_MPP24_31                   	0x0+#define DB_88F6180A_MPP32_39                   	0x4444c000+#define DB_88F6180A_MPP40_44                   	0x00044444+#define DB_88F6180A_OE_LOW                       0x0+#define DB_88F6180A_OE_HIGH                      0x0+#define DB_88F6180A_OE_VAL_LOW                   0x0+#define DB_88F6180A_OE_VAL_HIGH                  0x0++/* RD-88F6281A_PCAC */+#define RD_88F6281A_PCAC_MPP0_7                	0x21111111+#define RD_88F6281A_PCAC_MPP8_15               	0x00003311+#define RD_88F6281A_PCAC_MPP16_23              	0x00001100+#define RD_88F6281A_PCAC_MPP24_31              	0x00000000+#define RD_88F6281A_PCAC_MPP32_39              	0x00000000+#define RD_88F6281A_PCAC_MPP40_47              	0x00000000+#define RD_88F6281A_PCAC_MPP48_55              	0x00000000+#define RD_88F6281A_PCAC_OE_LOW                 0x0+#define RD_88F6281A_PCAC_OE_HIGH                0x0+#define RD_88F6281A_PCAC_OE_VAL_LOW             0x0+#define RD_88F6281A_PCAC_OE_VAL_HIGH            0x0++/* SHEEVA PLUG */+#define RD_SHEEVA_PLUG_MPP0_7                   0x01111111+#define RD_SHEEVA_PLUG_MPP8_15                  0x11113322+#define RD_SHEEVA_PLUG_MPP16_23                 0x00001111+#define RD_SHEEVA_PLUG_MPP24_31                 0x00100000+#define RD_SHEEVA_PLUG_MPP32_39                 0x00000000+#define RD_SHEEVA_PLUG_MPP40_47                 0x00000000+#define RD_SHEEVA_PLUG_MPP48_55                 0x00000000+#define RD_SHEEVA_PLUG_OE_LOW                   0x0+#define RD_SHEEVA_PLUG_OE_HIGH                  0x0+#define RD_SHEEVA_PLUG_OE_VAL_LOW               (BIT29)+#define RD_SHEEVA_PLUG_OE_VAL_HIGH              ((~(BIT17 | BIT16 | BIT15)) | BIT14) ++/* DB-CUSTOMER */+#define DB_CUSTOMER_MPP0_7                	    0x21111111+#define DB_CUSTOMER_MPP8_15               	    0x00003311+#define DB_CUSTOMER_MPP16_23              	    0x00001100+#define DB_CUSTOMER_MPP24_31              	    0x00000000+#define DB_CUSTOMER_MPP32_39              	    0x00000000+#define DB_CUSTOMER_MPP40_47              	    0x00000000+#define DB_CUSTOMER_MPP48_55              	    0x00000000+#define DB_CUSTOMER_OE_LOW                      0x0+#define DB_CUSTOMER_OE_HIGH                     (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))+#define DB_CUSTOMER_OE_VAL_LOW                  0x0+#define DB_CUSTOMER_OE_VAL_HIGH                 0x0++#endif /* __INCmvBoardEnvSpech */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c	2010-11-09 20:28:07.522495500 +0100@@ -0,0 +1,320 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#include "cpu/mvCpu.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvRegs.h"+#include "ctrlEnv/sys/mvCpuIfRegs.h"++/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif	++/* locals */++/*******************************************************************************+* mvCpuPclkGet - Get the CPU pClk (pipe clock)+*+* DESCRIPTION:+*       This routine extract the CPU core clock.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit clock cycles in MHertz.+*+*******************************************************************************/+/* 6180 have different clk reset sampling */++static MV_U32 mvCpu6180PclkGet(MV_VOID)+{+	MV_U32 	tmpPClkRate=0;+	MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;++	tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);+	tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;+	tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;+			+	tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;++	return tmpPClkRate;+}+++MV_U32 mvCpuPclkGet(MV_VOID)+{+#if defined(PCLCK_AUTO_DETECT)+	MV_U32 	tmpPClkRate=0;+	MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;++	if(mvCtrlModelGet() == MV_6180_DEV_ID)+		return mvCpu6180PclkGet();++	tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);+	tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);+	tmpPClkRate = cpuCLK[tmpPClkRate];++	return tmpPClkRate;+#else+	return MV_DEFAULT_PCLK+#endif+}++/*******************************************************************************+* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)+*+* DESCRIPTION:+*       This routine extract the CPU L2 clock.+*+* RETURN:+*       32bit clock cycles in Hertz.+*+*******************************************************************************/+static MV_U32  mvCpu6180L2ClkGet(MV_VOID)+{+	MV_U32 	L2ClkRate=0;+	MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;++	L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);+	L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;+	L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;+			+	L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;++	return L2ClkRate;++}++MV_U32  mvCpuL2ClkGet(MV_VOID)+{+#ifdef L2CLK_AUTO_DETECT+	MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;+	MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;++	if(mvCtrlModelGet() == MV_6180_DEV_ID)+		return mvCpu6180L2ClkGet();++	pClkRate = mvCpuPclkGet();++	tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);+	indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);++	L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);++	return L2ClkRate;+#else+	return MV_BOARD_DEFAULT_L2CLK;+#endif+}+++/*******************************************************************************+* mvCpuNameGet - Get CPU name+*+* DESCRIPTION:+*       This function returns a string describing the CPU model and revision.+*+* INPUT:+*       None.+*+* OUTPUT:+*       pNameBuff - Buffer to contain board name string. Minimum size 32 chars.+*+* RETURN:+*       None.+*******************************************************************************/+MV_VOID mvCpuNameGet(char *pNameBuff)+{+    MV_U32 cpuModel;+    +    cpuModel = mvOsCpuPartGet();++    /* The CPU module is indicated in the Processor Version Register (PVR) */+    switch(cpuModel)+    {+        case CPU_PART_MRVL131:+            mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());+            break;+        case CPU_PART_ARM926:+            mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());+            break;+	case CPU_PART_ARM946:+		mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());+		break;+        default:+            mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());+            break;+    }  /* switch  */++    return;+}+++#define MV_PROC_STR_SIZE 50++static void mvCpuIfGetL2EccMode(MV_8 *buf)+{+    MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);+    if (regVal & BIT2)+	mvOsSPrintf(buf, "L2 ECC Enabled");+    else+	mvOsSPrintf(buf, "L2 ECC Disabled");+}++static void mvCpuIfGetL2Mode(MV_8 *buf)+{+    MV_U32 regVal = 0;+    __asm volatile ("mrc	p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */+    if (regVal & BIT22)+	mvOsSPrintf(buf, "L2 Enabled");+    else+	mvOsSPrintf(buf, "L2 Disabled");+}++static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)+{+    MV_U32 regVal = 0;+    __asm volatile ("mrc	p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */+    if (regVal & BIT24)+	mvOsSPrintf(buf, "L2 Prefetch Disabled");+    else+	mvOsSPrintf(buf, "L2 Prefetch Enabled");+}++static void mvCpuIfGetWriteAllocMode(MV_8 *buf)+{+    MV_U32 regVal = 0;+    __asm volatile ("mrc	p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */+    if (regVal & BIT28)+	mvOsSPrintf(buf, "Write Allocate Enabled");+    else+	mvOsSPrintf(buf, "Write Allocate Disabled");+}++static void mvCpuIfGetCpuStreamMode(MV_8 *buf)+{+    MV_U32 regVal = 0;+    __asm volatile ("mrc	p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */+    if (regVal & BIT29)+	mvOsSPrintf(buf, "CPU Streaming Enabled");+    else+	mvOsSPrintf(buf, "CPU Streaming Disabled");+}++static void mvCpuIfPrintCpuRegs(void)+{+    MV_U32 regVal = 0;++    __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */+    mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);++   __asm volatile ("mrc	p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */+   mvOsPrintf("Control Reg = 0x%x\n",regVal);++   __asm volatile ("mrc	p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */+    mvOsPrintf("ID Code Reg = 0x%x\n",regVal);++   __asm volatile ("mrc	p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */+   mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);++}++MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)+{+  MV_U32 count = 0;+  +  MV_8 L2_ECC_str[MV_PROC_STR_SIZE];+  MV_8 L2_En_str[MV_PROC_STR_SIZE];+  MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];+  MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];+  MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];+  +  mvCpuIfGetL2Mode(L2_En_str);+  mvCpuIfGetL2EccMode(L2_ECC_str); +  mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);+  mvCpuIfGetWriteAllocMode(Write_Alloc_str);+  mvCpuIfGetCpuStreamMode(Cpu_Stream_str);+  mvCpuIfPrintCpuRegs();+  +  count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);+  count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);+  count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);+  count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);+  count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);+  return count;+}++MV_U32 whoAmI(MV_VOID)+{+	return 0;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h	2010-11-09 20:28:07.562495452 +0100@@ -0,0 +1,99 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvCpuh+#define __INCmvCpuh++#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"++/* defines */+#define CPU_PART_MRVL131      0x131+#define CPU_PART_ARM926       0x926+#define CPU_PART_ARM946       0x946+#define MV_CPU_ARM_CLK_ELM_SIZE	    12+#define MV_CPU_ARM_CLK_RATIO_OFF    8+#define MV_CPU_ARM_CLK_DDR_OFF	    4++#ifndef MV_ASMLANGUAGE+typedef struct _mvCpuArmClk +{+	MV_U32	      cpuClk;	  /* CPU clock in MHz */+	MV_U32	      ddrClk;	  /* DDR clock in MHz */+	MV_U32	      l2Clk;	  /* CPU DDR clock ratio */++}MV_CPU_ARM_CLK;++MV_U32    mvCpuPclkGet(MV_VOID);+MV_VOID   mvCpuNameGet(char *pNameBuff);+MV_U32  mvCpuL2ClkGet(MV_VOID);+MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);+MV_U32 whoAmI(MV_VOID);++#endif /* MV_ASMLANGUAGE */+++#endif /* __INCmvCpuh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c	2010-11-09 20:28:07.602495466 +0100@@ -0,0 +1,296 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/*******************************************************************************+* mvCtrlEnvAddrDec.h - Marvell controller address decode library+*+* DESCRIPTION:+*+* DEPENDENCIES:+*       None.+*+*******************************************************************************/++/* includes */+#include "ctrlEnv/mvCtrlEnvAddrDec.h"+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"+#include "ddr2/mvDramIfRegs.h"+#include "pex/mvPexRegs.h"++#define MV_DEBUG++/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif+	+/* Default Attributes array */+MV_TARGET_ATTRIB	mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;+extern MV_TARGET 	*sampleAtResetTargetArray;+/* Dram\AHBToMbus\PEX share regsiter */++#define CTRL_DEC_BASE_OFFS		16+#define CTRL_DEC_BASE_MASK		(0xffff << CTRL_DEC_BASE_OFFS)+#define CTRL_DEC_BASE_ALIGNMENT	0x10000++#define CTRL_DEC_SIZE_OFFS		16+#define CTRL_DEC_SIZE_MASK		(0xffff << CTRL_DEC_SIZE_OFFS)+#define CTRL_DEC_SIZE_ALIGNMENT	0x10000++#define CTRL_DEC_WIN_EN			BIT0++++/*******************************************************************************+* mvCtrlAddrDecToReg - Get address decode register format values+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*+*******************************************************************************/+MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)+{++	MV_U32 baseToReg=0 , sizeToReg=0;+    +	/* BaseLow[31:16] => base register [31:16]		*/+	baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;++	/* Write to address decode Base Address Register                  */+	pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;+	pAddrDecRegs->baseReg |= baseToReg;++	/* Get size register value according to window size						*/+	sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);+	+	/* Size parameter validity check.                                   */+	if (-1 == sizeToReg)+	{+		return MV_BAD_PARAM;+	}++	/* set size */+	pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;+	pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);+	++	return MV_OK;++}++/*******************************************************************************+* mvCtrlRegToAddrDec - Extract address decode struct from registers.+*+* DESCRIPTION:+*       This function extract address decode struct from address decode +*       registers given as parameters.+*+* INPUT:+*       pAddrDecRegs - Address decode register struct.+*+* OUTPUT:+*       pAddrDecWin - Target window data structure.+*+* RETURN:+*		MV_BAD_PARAM if address decode registers data is invalid.+*+*******************************************************************************/+MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)+{+	MV_U32 sizeRegVal;+	+	sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >> +					CTRL_DEC_SIZE_OFFS;++	pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);+++	/* Extract base address						*/+	/* Base register [31:16] ==> baseLow[31:16] 		*/+	pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;++	pAddrDecWin->baseHigh =  0;++	return MV_OK;+    +}++/*******************************************************************************+* mvCtrlAttribGet - +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*+*******************************************************************************/++MV_STATUS mvCtrlAttribGet(MV_TARGET target,+						  MV_TARGET_ATTRIB *targetAttrib)+{++	targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;+	targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;++	return MV_OK;++}++/*******************************************************************************+* mvCtrlGetAttrib - +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*+*******************************************************************************/+MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)+{+	MV_TARGET target;+	MV_TARGET x;+	for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)+	{+		x = MV_CHANGE_BOOT_CS(target);+		if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&+			(mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))+		{+			/* found it */+			break;+		}+	}++	return target;+}++MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin, +                                MV_DEC_WIN_PARAMS *pWinParam)+{+	MV_U32 baseToReg=0, sizeToReg=0;+    +	/* BaseLow[31:16] => base register [31:16]		*/+	baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;++	/* Write to address decode Base Address Register                  */+	pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;+	pWinParam->baseAddr |= baseToReg;++	/* Get size register value according to window size						*/+	sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);+	+	/* Size parameter validity check.                                   */+	if (-1 == sizeToReg)+	{+        mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");+		return MV_BAD_PARAM;+	}+    pWinParam->size = sizeToReg;++    pWinParam->attrib   = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;+    pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;++    return MV_OK;+}++MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam, +                                MV_DEC_WIN *pAddrDecWin)+{+    MV_TARGET_ATTRIB    targetAttrib;++    pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;+	+	/* Upper 32bit address base is supported under PCI High Address remap */+	pAddrDecWin->addrWin.baseHigh = 0;	++	/* Prepare sizeReg to ctrlRegToSize function */+    pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);++	if (-1 == pAddrDecWin->addrWin.size)+	{+		DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));+		return MV_BAD_PARAM;+	}+    targetAttrib.targetId = pWinParam->targetId;+    targetAttrib.attrib = pWinParam->attrib;++    pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++    return MV_OK;+}+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h	2010-11-09 20:28:07.642495620 +0100@@ -0,0 +1,203 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvCtrlEnvAddrDech+#define __INCmvCtrlEnvAddrDech++/* includes */+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvRegs.h"+++/* defines  */+/* DUnit attributes */+#define ATMWCR_WIN_DUNIT_CS0_OFFS			0+#define ATMWCR_WIN_DUNIT_CS0_MASK			BIT0+#define ATMWCR_WIN_DUNIT_CS0_REQ			(0 << ATMWCR_WIN_DUNIT_CS0_OFFS)++#define ATMWCR_WIN_DUNIT_CS1_OFFS			1+#define ATMWCR_WIN_DUNIT_CS1_MASK			BIT1+#define ATMWCR_WIN_DUNIT_CS1_REQ 			(0 << ATMWCR_WIN_DUNIT_CS1_OFFS)++#define ATMWCR_WIN_DUNIT_CS2_OFFS			2+#define ATMWCR_WIN_DUNIT_CS2_MASK			BIT2+#define ATMWCR_WIN_DUNIT_CS2_REQ 			(0 << ATMWCR_WIN_DUNIT_CS2_OFFS)++#define ATMWCR_WIN_DUNIT_CS3_OFFS			3+#define ATMWCR_WIN_DUNIT_CS3_MASK			BIT3+#define ATMWCR_WIN_DUNIT_CS3_REQ 			(0 << ATMWCR_WIN_DUNIT_CS3_OFFS)++/* RUnit (Device)  attributes */+#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS		0+#define ATMWCR_WIN_RUNIT_DEVCS0_MASK		BIT0+#define ATMWCR_WIN_RUNIT_DEVCS0_REQ			(0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)++#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS		1+#define ATMWCR_WIN_RUNIT_DEVCS1_MASK		BIT1+#define ATMWCR_WIN_RUNIT_DEVCS1_REQ 		(0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)++#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS		2+#define ATMWCR_WIN_RUNIT_DEVCS2_MASK		BIT2+#define ATMWCR_WIN_RUNIT_DEVCS2_REQ 		(0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)++#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS		4+#define ATMWCR_WIN_RUNIT_BOOTCS_MASK		BIT4+#define ATMWCR_WIN_RUNIT_BOOTCS_REQ 		(0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)++/* LMaster (PCI)  attributes */+#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS		0+#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK		BIT0+#define ATMWCR_WIN_LUNIT_BYTE_SWP			(0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)+#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP		(1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)+++#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS		1+#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK		BIT1+#define ATMWCR_WIN_LUNIT_WORD_SWP			(0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)+#define ATMWCR_WIN_LUNIT_WORD_NO_SWP		(1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)++#define ATMWCR_WIN_LUNIT_NO_SNOOP			BIT2++#define ATMWCR_WIN_LUNIT_TYPE_OFFS			3+#define ATMWCR_WIN_LUNIT_TYPE_MASK			BIT3+#define ATMWCR_WIN_LUNIT_TYPE_IO			(0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)+#define ATMWCR_WIN_LUNIT_TYPE_MEM			(1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)++#define ATMWCR_WIN_LUNIT_FORCE64_OFFS		4+#define ATMWCR_WIN_LUNIT_FORCE64_MASK		BIT4+#define ATMWCR_WIN_LUNIT_FORCE64			(0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)++#define ATMWCR_WIN_LUNIT_ORDERING_OFFS		6+#define ATMWCR_WIN_LUNIT_ORDERING_MASK		BIT6+#define ATMWCR_WIN_LUNIT_ORDERING			(1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)++/* PEX Attributes */+#define ATMWCR_WIN_PEX_TYPE_OFFS			3+#define ATMWCR_WIN_PEX_TYPE_MASK			BIT3+#define ATMWCR_WIN_PEX_TYPE_IO				(0 << ATMWCR_WIN_PEX_TYPE_OFFS)+#define ATMWCR_WIN_PEX_TYPE_MEM				(1 << ATMWCR_WIN_PEX_TYPE_OFFS)++/* typedefs */++/* Unsupported attributes for address decode:                               */+/* 2) PCI0/1_REQ64n control                                                 */++typedef struct _mvDecRegs+{+	MV_U32 baseReg;+    MV_U32 baseRegHigh;+    MV_U32 sizeReg;++}MV_DEC_REGS;++typedef struct _mvTargetAttrib+{+	MV_U8			attrib;			/* chip select attributes */+	MV_TARGET_ID 		targetId; 		/* Target Id of this MV_TARGET */++}MV_TARGET_ATTRIB;+++/* This structure describes address decode window                           */+typedef struct _mvDecWin +{+    MV_TARGET       target;         /* Target for addr decode window        */+    MV_ADDR_WIN     addrWin;        /* Address window of target             */+    MV_BOOL     	enable;         /* Window enable/disable                */+}MV_DEC_WIN;++typedef struct _mvDecWinParams+{+    MV_TARGET_ID    targetId;   /* Target ID field */+    MV_U8           attrib;     /* Attribute field */+    MV_U32          baseAddr;   /* Base address in register format */+    MV_U32          size;       /* Size in register format */+}MV_DEC_WIN_PARAMS;+++/* mvCtrlEnvAddrDec API list */++MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,+							 MV_DEC_REGS *pAddrDecRegs);++MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,+							 MV_ADDR_WIN *pAddrDecWin);++MV_STATUS mvCtrlAttribGet(MV_TARGET target,+						  MV_TARGET_ATTRIB *targetAttrib);++MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);+++MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin, +                                MV_DEC_WIN_PARAMS *pWinParam);++MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam, +                                MV_DEC_WIN *pAddrDecWin);+++++#endif /* __INCmvCtrlEnvAddrDech */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h	2010-11-09 20:28:07.682495401 +0100@@ -0,0 +1,98 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvCtrlEnvAsmh+#define __INCmvCtrlEnvAsmh+#include "pex/mvPexRegs.h"++#define CHIP_BOND_REG					0x10034+#define PCKG_OPT_MASK_AS 		#3+#define PXCCARI_REVID_MASK_AS           #PXCCARI_REVID_MASK++/* Read device ID into toReg bits 15:0 from 0xd0000000 */+/* defines  */+#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \+        MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\+        and     toReg, toReg, PCKG_OPT_MASK_AS                 /* Mask for package ID */++/* Read device ID into toReg bits 15:0 from 0xf1000000*/+#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \+        MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\+        and     toReg, toReg, PCKG_OPT_MASK_AS                  /* Mask for package ID */++/* Read Revision into toReg bits 7:0 0xd0000000*/+#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg)	\+        /* Read device revision */			\+        MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\+        and     toReg, toReg, PXCCARI_REVID_MASK_AS                  /* Mask for calss ID */++/* Read Revision into toReg bits 7:0 0xf1000000*/+#define MV_CTRL_REV_GET_ASM(toReg, tmpReg)	\+        /* Read device revision */			\+        MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\+        and     toReg, toReg, PXCCARI_REVID_MASK_AS                  /* Mask for calss ID */+++#endif /* __INCmvCtrlEnvAsmh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c	2010-11-09 20:28:07.712495488 +0100@@ -0,0 +1,1825 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++/* includes */+#include "mvCommon.h"+#include "mvCtrlEnvLib.h"+#include "ctrlEnv/sys/mvCpuIf.h"++#if defined(MV_INCLUDE_PEX)+#include "pex/mvPex.h"+#include "ctrlEnv/sys/mvSysPex.h"+#endif++#if defined(MV_INCLUDE_GIG_ETH)+#include "ctrlEnv/sys/mvSysGbe.h"+#endif++#if defined(MV_INCLUDE_XOR)+#include "ctrlEnv/sys/mvSysXor.h"+#endif++#if defined(MV_INCLUDE_SATA)+#include "ctrlEnv/sys/mvSysSata.h"+#endif++#if defined(MV_INCLUDE_USB)+#include "ctrlEnv/sys/mvSysUsb.h"+#endif++#if defined(MV_INCLUDE_AUDIO)+#include "ctrlEnv/sys/mvSysAudio.h"+#endif++#if defined(MV_INCLUDE_CESA)+#include "ctrlEnv/sys/mvSysCesa.h"+#endif++#if defined(MV_INCLUDE_TS)+#include "ctrlEnv/sys/mvSysTs.h"+#endif++/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif	++/*******************************************************************************+* mvCtrlEnvInit - Initialize Marvell controller environment.+*+* DESCRIPTION:+*       This function get environment information and initialize controller+*       internal/external environment. For example+*       1) MPP settings according to board MPP macros.+*		NOTE: It is the user responsibility to shut down all DMA channels+*		in device and disable controller sub units interrupts during +*		boot process.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvCtrlEnvInit(MV_VOID)+{+    	MV_U32 mppGroup;+	MV_U32 devId;+	MV_U32 boardId;+	MV_U32 i;+	MV_U32 maxMppGrp = 1;+	MV_U32 mppVal = 0;+	MV_U32 bootVal = 0;+	MV_U32 mppGroupType = 0;+	MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;+	MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;++	devId = mvCtrlModelGet();+	boardId= mvBoardIdGet();++	switch(devId){+		case MV_6281_DEV_ID:+			maxMppGrp = MV_6281_MPP_MAX_GROUP;+			break;+		case MV_6192_DEV_ID:+			maxMppGrp = MV_6192_MPP_MAX_GROUP;+			break;+        case MV_6190_DEV_ID:+            maxMppGrp = MV_6190_MPP_MAX_GROUP;+            break;+		case MV_6180_DEV_ID:+			maxMppGrp = MV_6180_MPP_MAX_GROUP;+			break;		+	}+	+	/* MPP Init */+	/* We split mpp init to 3 phases:+	 * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write +	 * in phase 2.+	 * 2. We detect the mpp group type and according the mpp values [35:20].+	 * 3. We detect the mpp group type and according the mpp values [49:36].+	 */+	/* Mpp phase 1 mpp[19:0] */+	/* Read MPP group from board level and assign to MPP register */+	for (mppGroup = 0; mppGroup < 3; mppGroup++)+	{+		mppVal = mvBoardMppGet(mppGroup);+		if (mppGroup == 0)+		{+		    bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));+		    if (mvCtrlIsBootFromSPI())+		    {+			mppVal &= ~0xffff;+			bootVal &= 0xffff;+			mppVal |= bootVal;+		    }+		    else if (mvCtrlIsBootFromSPIUseNAND())+		    {+			mppVal &= ~0xf0000000;+			bootVal &= 0xf0000000;+			mppVal |= bootVal;+		    }+		    else if (mvCtrlIsBootFromNAND())+		    {+			mppVal &= ~0xffffff;+			bootVal &= 0xffffff;+			mppVal |= bootVal;+		    }+		}+		+		if (mppGroup == 2)+		{+		    bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));+		    if (mvCtrlIsBootFromNAND())+		    {+			mppVal &= ~0xff00;+			bootVal &= 0xff00;+			mppVal |= bootVal;+		    }+		}++		MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);+	}++	/* Identify MPPs group */+	mvBoardMppGroupIdUpdate();++	/* Update MPPs mux relevent only on Marvell DB */+	if ((boardId == DB_88F6281A_BP_ID) ||+		(boardId == DB_88F6180A_BP_ID))+		mvBoardMppMuxSet();++	mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);++	/* Mpp phase 2 */+	/* Read MPP group from board level and assign to MPP register */+    if (devId != MV_6180_DEV_ID)+    {+        i = 0;+    	for (mppGroup = 2; mppGroup < 5; mppGroup++)+    	{+    		if ((mppGroupType == MV_BOARD_OTHER) ||+    			(boardId == RD_88F6281A_ID) ||+    			(boardId == RD_88F6192A_ID) ||+                (boardId == RD_88F6190A_ID) ||+                (boardId == RD_88F6281A_PCAC_ID) ||+                (boardId == SHEEVA_PLUG_ID))+    			mppVal = mvBoardMppGet(mppGroup);+    		else+    		{+    			mppVal = mppGroup1[mppGroupType][i];+    			i++;+    		}+    +    		/* Group 2 is shared mpp[23:16] */+    		if (mppGroup == 2)+    		{+                bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));+    			mppVal &= ~0xffff;+    			bootVal &= 0xffff;+    			mppVal |= bootVal;+    		}+    +    		MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);+    	}+    }++	if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))+		return MV_OK;+ 	+	/* Mpp phase 3 */+	mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);+	/* Read MPP group from board level and assign to MPP register */+	i = 0;+	for (mppGroup = 4; mppGroup < 7; mppGroup++)+	{+		if ((mppGroupType == MV_BOARD_OTHER) ||+			(boardId == RD_88F6281A_ID) ||+            (boardId == RD_88F6281A_PCAC_ID) ||+            (boardId == SHEEVA_PLUG_ID))+			mppVal = mvBoardMppGet(mppGroup);+		else+		{+			mppVal = mppGroup2[mppGroupType][i];+			i++;+		}++		/* Group 4 is shared mpp[35:32] */+		if (mppGroup == 4)+		{+            bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));+			mppVal &= ~0xffff;+			bootVal &= 0xffff;+			mppVal |= bootVal;+		}++		MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);+	}+    /* Update SSCG configuration register*/+    if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||+       mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)+        MV_REG_WRITE(0x100d8, 0x53);++	return MV_OK;+}++/*******************************************************************************+* mvCtrlMppRegGet - return reg address of mpp group+*+* DESCRIPTION:+*+* INPUT:+*       mppGroup - MPP group.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_U32 - Register address.+*+*******************************************************************************/+MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)+{+        MV_U32 ret;++        switch(mppGroup){+                case (0):       ret = MPP_CONTROL_REG0;+                                break;+                case (1):       ret = MPP_CONTROL_REG1;+                                break;+                case (2):       ret = MPP_CONTROL_REG2;+                                break;+                case (3):       ret = MPP_CONTROL_REG3;+                                break;+                case (4):       ret = MPP_CONTROL_REG4;+                                break;+                case (5):       ret = MPP_CONTROL_REG5;+                                break;+                case (6):       ret = MPP_CONTROL_REG6;+                                break;+                default:        ret = MPP_CONTROL_REG0;+                                break;+        }+        return ret;+}+#if defined(MV_INCLUDE_PEX) +/*******************************************************************************+* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.+*+* DESCRIPTION:+*       This function returns Marvell controller number of PEX interfaces.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Marvell controller number of PEX interfaces. If controller +*		ID is undefined the function returns '0'.+*+*******************************************************************************/+MV_U32 mvCtrlPexMaxIfGet(MV_VOID)+{++	return MV_PEX_MAX_IF;+}+#endif++#if defined(MV_INCLUDE_GIG_ETH)+/*******************************************************************************+* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.+*+* DESCRIPTION:+*       This function returns Marvell controller number of etherent port.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Marvell controller number of etherent port.+*+*******************************************************************************/+MV_U32 mvCtrlEthMaxPortGet(MV_VOID)+{+	MV_U32 devId;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			return MV_6281_ETH_MAX_PORTS;+			break;+		case MV_6192_DEV_ID:+			return MV_6192_ETH_MAX_PORTS;+			break;+        case MV_6190_DEV_ID:+            return MV_6190_ETH_MAX_PORTS;+            break;+		case MV_6180_DEV_ID:+			return MV_6180_ETH_MAX_PORTS;+			break;		+	}+	return 0;++}+#endif++#if defined(MV_INCLUDE_XOR)+/*******************************************************************************+* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.+*+* DESCRIPTION:+*       This function returns Marvell controller number of XOR channels.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Marvell controller number of XOR channels.+*+*******************************************************************************/+MV_U32 mvCtrlXorMaxChanGet(MV_VOID)+{+	return MV_XOR_MAX_CHAN; +}+#endif++#if defined(MV_INCLUDE_USB)+/*******************************************************************************+* mvCtrlUsbHostMaxGet - Get number of Marvell Usb  controllers+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       returns number of Marvell USB  controllers.+*+*******************************************************************************/+MV_U32 mvCtrlUsbMaxGet(void)+{+	return MV_USB_MAX_PORTS;+}+#endif+++#if defined(MV_INCLUDE_NAND)+/*******************************************************************************+* mvCtrlNandSupport - Return if this controller has integrated NAND flash support+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if NAND is supported and MV_FALSE otherwise+*+*******************************************************************************/+MV_U32	  mvCtrlNandSupport(MV_VOID)+{+	MV_U32 devId;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			return MV_6281_NAND;+			break;+		case MV_6192_DEV_ID:+			return MV_6192_NAND;+			break;+        case MV_6190_DEV_ID:+            return MV_6190_NAND;+            break;+		case MV_6180_DEV_ID:+			return MV_6180_NAND;+			break;		+	}+	return 0;++}+#endif++#if defined(MV_INCLUDE_SDIO)+/*******************************************************************************+* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if SDIO is supported and MV_FALSE otherwise+*+*******************************************************************************/+MV_U32	  mvCtrlSdioSupport(MV_VOID)+{+	MV_U32 devId;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			return MV_6281_SDIO;+			break;+		case MV_6192_DEV_ID:+			return MV_6192_SDIO;+			break;+        case MV_6190_DEV_ID:+            return MV_6190_SDIO;+            break;+		case MV_6180_DEV_ID:+			return MV_6180_SDIO;+			break;		+	}+	return 0;++}+#endif++#if defined(MV_INCLUDE_TS)+/*******************************************************************************+* mvCtrlTsSupport - Return if this controller has integrated TS flash support+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if TS is supported and MV_FALSE otherwise+*+*******************************************************************************/+MV_U32	  mvCtrlTsSupport(MV_VOID)+{+	MV_U32 devId;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			return MV_6281_TS;+			break;+		case MV_6192_DEV_ID:+			return MV_6192_TS;+			break;+        case MV_6190_DEV_ID:+            return MV_6190_TS;+            break;+		case MV_6180_DEV_ID:+			return MV_6180_TS;+			break;		+	}+	return 0;+}+#endif++#if defined(MV_INCLUDE_AUDIO)+/*******************************************************************************+* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if AUDIO is supported and MV_FALSE otherwise+*+*******************************************************************************/+MV_U32	  mvCtrlAudioSupport(MV_VOID)+{+	MV_U32 devId;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			return MV_6281_AUDIO;+			break;+		case MV_6192_DEV_ID:+			return MV_6192_AUDIO;+			break;+        case MV_6190_DEV_ID:+            return MV_6190_AUDIO;+            break;+		case MV_6180_DEV_ID:+			return MV_6180_AUDIO;+			break;		+	}+	return 0;++}+#endif++#if defined(MV_INCLUDE_TDM)+/*******************************************************************************+* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if TDM is supported and MV_FALSE otherwise+*+*******************************************************************************/+MV_U32	  mvCtrlTdmSupport(MV_VOID)+{+	MV_U32 devId;+	+	devId = mvCtrlModelGet();++	switch(devId){+		case MV_6281_DEV_ID:+			return MV_6281_TDM;+			break;+		case MV_6192_DEV_ID:+			return MV_6192_TDM;+			break;+        case MV_6190_DEV_ID:+            return MV_6190_TDM;+            break;+		case MV_6180_DEV_ID:+			return MV_6180_TDM;+			break;		+	}+	return 0;++}+#endif++/*******************************************************************************+* mvCtrlModelGet - Get Marvell controller device model (Id)+*+* DESCRIPTION:+*       This function returns 16bit describing the device model (ID) as defined+*       in PCI Device and Vendor ID configuration register offset 0x0.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       16bit desscribing Marvell controller ID +*+*******************************************************************************/+MV_U16 mvCtrlModelGet(MV_VOID)+{+	MV_U32 devId;+	+	devId = MV_REG_READ(CHIP_BOND_REG);+	devId &= PCKG_OPT_MASK;++	switch(devId){+		case 2:+			return	MV_6281_DEV_ID;+			break;+    case 1:+            if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)+                 == MV_6190_DEV_ID)+                return	MV_6190_DEV_ID;+            else+                return	MV_6192_DEV_ID;+			break;+		case 0:+			return	MV_6180_DEV_ID;+			break;+	}++	return 0;+}+/*******************************************************************************+* mvCtrlRevGet - Get Marvell controller device revision number+*+* DESCRIPTION:+*       This function returns 8bit describing the device revision as defined+*       in PCI Express Class Code and Revision ID Register.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       8bit desscribing Marvell controller revision number +*+*******************************************************************************/+MV_U8 mvCtrlRevGet(MV_VOID)+{+	MV_U8 revNum;+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)+	/* Check pex power state */+	MV_U32 pexPower;+	pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);+	if (pexPower == MV_FALSE)+		mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);+#endif+	revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)+	/* Return to power off state */+	if (pexPower == MV_FALSE)+		mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);+#endif+	return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);+}++/*******************************************************************************+* mvCtrlNameGet - Get Marvell controller name+*+* DESCRIPTION:+*       This function returns a string describing the device model and revision.+*+* INPUT:+*       None.+*+* OUTPUT:+*       pNameBuff - Buffer to contain device name string. Minimum size 30 chars.+*+* RETURN:+*       +*       MV_ERROR if informantion can not be read.+*******************************************************************************/+MV_STATUS mvCtrlNameGet(char *pNameBuff)+{+	mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX, +				mvCtrlModelGet(), mvCtrlRevGet()); +	+	return MV_OK;+}++/*******************************************************************************+* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision+*+* DESCRIPTION:+*       This function returns 32bit value describing both Device ID and Revision+*       as defined in PCI Express Device and Vendor ID Register and device revision+*	    as defined in PCI Express Class Code and Revision ID Register.+     +*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit describing both controller device ID and revision number+*+*******************************************************************************/+MV_U32	mvCtrlModelRevGet(MV_VOID)+{+	return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());+}++/*******************************************************************************+* mvCtrlModelRevNameGet - Get Marvell controller name+*+* DESCRIPTION:+*       This function returns a string describing the device model and revision.+*+* INPUT:+*       None.+*+* OUTPUT:+*       pNameBuff - Buffer to contain device name string. Minimum size 30 chars.+*+* RETURN:+*       +*       MV_ERROR if informantion can not be read.+*******************************************************************************/++MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)+{++        switch (mvCtrlModelRevGet())+        {+        case MV_6281_A0_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME); +                break;+        case MV_6192_A0_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME); +                break;+        case MV_6180_A0_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME); +                break;+        case MV_6190_A0_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME); +                break;+        case MV_6281_A1_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);+                break;+        case MV_6192_A1_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);+                break;+        case MV_6180_A1_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);+                break;+        case MV_6190_A1_ID:+                mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);+                break;+        default:+                mvCtrlNameGet(pNameBuff);+                break;+        }++        return MV_OK;+}+++/*******************************************************************************+* ctrlWinOverlapTest - Test address windows for overlaping.+*+* DESCRIPTION:+*       This function checks the given two address windows for overlaping.+*+* INPUT:+*       pAddrWin1 - Address window 1.+*       pAddrWin2 - Address window 2.+*+* OUTPUT:+*       None.+*+* RETURN:+*       +*       MV_TRUE if address window overlaps, MV_FALSE otherwise.+*******************************************************************************/+MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)+{+    MV_U32 winBase1, winBase2;+    MV_U32 winTop1, winTop2;+    +	/* check if we have overflow than 4G*/+	if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||+	   ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))+	{+		return MV_TRUE;+	}++    winBase1 = pAddrWin1->baseLow;+    winBase2 = pAddrWin2->baseLow;+    winTop1  = winBase1 + pAddrWin1->size-1;+    winTop2  = winBase2 + pAddrWin2->size-1;++    +    if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||+        ((winBase1 <= winBase2) && (winBase2 <= winTop1)))+    {+        return MV_TRUE;+    }+    else+    {+        return MV_FALSE;+    }+}++/*******************************************************************************+* ctrlWinWithinWinTest - Test address windows for overlaping.+*+* DESCRIPTION:+*       This function checks the given win1 boundries is within+*		win2 boundries.+*+* INPUT:+*       pAddrWin1 - Address window 1.+*       pAddrWin2 - Address window 2.+*+* OUTPUT:+*       None.+*+* RETURN:+*       +*       MV_TRUE if found win1 inside win2, MV_FALSE otherwise.+*******************************************************************************/+MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)+{+    MV_U32 winBase1, winBase2;+    MV_U32 winTop1, winTop2;+    +    winBase1 = pAddrWin1->baseLow;+    winBase2 = pAddrWin2->baseLow;+    winTop1  = winBase1 + pAddrWin1->size -1;+    winTop2  = winBase2 + pAddrWin2->size -1;+    +    if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||+        ((winTop1  >= winBase2) && (winTop1 <= winTop2)))+    {+        return MV_TRUE;+    }+    else+    {+        return MV_FALSE;+    }+}++static const char* cntrlName[] = TARGETS_NAME_ARRAY;++/*******************************************************************************+* mvCtrlTargetNameGet - Get Marvell controller target name+*+* DESCRIPTION:+*       This function convert the trget enumeration to string.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Target name (const MV_8 *)+*******************************************************************************/+const MV_8* mvCtrlTargetNameGet( MV_TARGET target )+{++	if (target >= MAX_TARGETS)+	{+		return "target unknown";+	}++	return cntrlName[target];+}++/*******************************************************************************+* mvCtrlAddrDecShow - Print the Controller units address decode map.+*+* DESCRIPTION:+*		This function the Controller units address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvCtrlAddrDecShow(MV_VOID)+{+    mvCpuIfAddDecShow();+    mvAhbToMbusAddDecShow();+#if defined(MV_INCLUDE_PEX)+	mvPexAddrDecShow();+#endif+#if defined(MV_INCLUDE_USB)+    	mvUsbAddrDecShow();+#endif+#if defined(MV_INCLUDE_GIG_ETH)+	mvEthAddrDecShow();+#endif+#if defined(MV_INCLUDE_XOR)+	mvXorAddrDecShow();+#endif+#if defined(MV_INCLUDE_SATA)+    mvSataAddrDecShow();+#endif+#if defined(MV_INCLUDE_AUDIO)+    mvAudioAddrDecShow();+#endif+#if defined(MV_INCLUDE_TS)+    mvTsuAddrDecShow();+#endif+}++/*******************************************************************************+* ctrlSizeToReg - Extract size value for register assignment.+*+* DESCRIPTION:		+*       Address decode size parameter must be programed from LSB to MSB as+*       sequence of 1's followed by sequence of 0's. The number of 1's +*       specifies the size of the window in 64 KB granularity (e.g. a +*       value of 0x00ff specifies 256x64k = 16 MB).+*       This function extract the size value from the size parameter according +*		to given aligment paramter. For example for size 0x1000000 (16MB) and +*		aligment 0x10000 (64KB) the function will return 0x00FF.+*+* INPUT:+*       size - Size.+*		alignment - Size alignment.	Note that alignment must be power of 2!+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit describing size register value correspond to size parameter. +*		If value is '-1' size parameter or aligment are invalid.+*******************************************************************************/+MV_U32	ctrlSizeToReg(MV_U32 size, MV_U32 alignment)+{+	MV_U32 retVal;++	/* Check size parameter alignment		*/+	if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))+	{+		DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));+		return -1;+	}+	+	/* Take out the "alignment" portion out of the size parameter */+	alignment--;	/* Now the alignmet is a sequance of '1' (e.g. 0xffff) 		*/+					/* and size is 0x1000000 (16MB) for example	*/+	while(alignment & 1)	/* Check that alignmet LSB is set	*/+	{+		size = (size >> 1); /* If LSB is set, move 'size' one bit to right	*/	+		alignment = (alignment >> 1);+	}+	+	/* If after the alignment first '0' was met we still have '1' in 		*/+	/* it then aligment is invalid (not power of 2) 				*/+	if (alignment)+	{+		DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n", +			(MV_U32)alignment));+		return -1;+	}++	/* Now the size is shifted right according to aligment: 0x0100			*/+	size--;         /* Now the size is a sequance of '1': 0x00ff 			*/+    +	retVal = size ;+	+	/* Check that LSB to MSB is sequence of 1's followed by sequence of 0's		*/+	while(size & 1)	/* Check that LSB is set	*/+	{+		size = (size >> 1); /* If LSB is set, move one bit to the right		*/	+	}++    if (size) /* Sequance of 1's is over. Check that we have no other 1's		*/+	{+		DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n", +                                                                        size));+		return -1;+	}+	+    return retVal;+	+}++/*******************************************************************************+* ctrlRegToSize - Extract size value from register value.+*+* DESCRIPTION:		+*       This function extract a size value from the register size parameter +*		according to given aligment paramter. For example for register size +*		value 0xff and aligment 0x10000 the function will return 0x01000000.+*+* INPUT:+*       regSize   - Size as in register format.	See ctrlSizeToReg.+*		alignment - Size alignment.	Note that alignment must be power of 2!+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit describing size. +*		If value is '-1' size parameter or aligment are invalid.+*******************************************************************************/+MV_U32	ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)+{+   	MV_U32 temp;++	/* Check that LSB to MSB is sequence of 1's followed by sequence of 0's		*/ +	temp = regSize;		/* Now the size is a sequance of '1': 0x00ff		*/+	+	while(temp & 1)	/* Check that LSB is set					*/+	{+		temp = (temp >> 1); /* If LSB is set, move one bit to the right		*/	+	}++    if (temp) /* Sequance of 1's is over. Check that we have no other 1's		*/+	{+		DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n", +					regSize));+	   	return -1;+	}+	++	/* Check that aligment is a power of two					*/+	temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) 		*/+					+	while(temp & 1)	/* Check that alignmet LSB is set				*/+	{+		temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right	*/	+	}+	+	/* If after the 'temp' first '0' was met we still have '1' in 'temp'		*/+	/* then 'temp' is invalid (not power of 2) 					*/+	if (temp)+	{+		DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n", +					alignment));+		return -1;+	}++	regSize++;      /* Now the size is 0x0100					*/++	/* Add in the "alignment" portion to the register size parameter 		*/+	alignment--;	/* Now the alignmet is a sequance of '1' (e.g. 0xffff) 		*/++	while(alignment & 1)	/* Check that alignmet LSB is set			*/+	{+		regSize   = (regSize << 1); /* LSB is set, move 'size' one bit left	*/	+		alignment = (alignment >> 1);+	}+		+    return regSize;	+}+++/*******************************************************************************+* ctrlSizeRegRoundUp - Round up given size +*+* DESCRIPTION:		+*       This function round up a given size to a size that fits the +*       restrictions of size format given an aligment parameter.+*		to given aligment paramter. For example for size parameter 0xa1000 and +*		aligment 0x1000 the function will return 0xFF000.+*+* INPUT:+*       size - Size.+*		alignment - Size alignment.	Note that alignment must be power of 2!+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit describing size value correspond to size in register.  +*******************************************************************************/+MV_U32	ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)+{+	MV_U32 msbBit = 0;+    MV_U32 retSize;+	+    /* Check if size parameter is already comply with restriction		*/+	if (!(-1 == ctrlSizeToReg(size, alignment)))+	{+		return size;+	}+    +    while(size)+	{+		size = (size >> 1);+        msbBit++;+	}++    retSize = (1 << msbBit);+    +    if (retSize < alignment)+    {+        return alignment;+    }+    else+    {+        return retSize;+    }+}+/*******************************************************************************+* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button +* 				 was pressed and clear counter+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN: number of milliseconds the reset button was pressed +*******************************************************************************/+MV_U32	mvCtrlSysRstLengthCounterGet(MV_VOID)+{+	static volatile MV_U32 Count = 0;++	if(!Count) {+		Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);+		Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));+		/* clear counter for next boot */+		MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);	+	}++	DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));++	return Count;		+}++MV_BOOL	  mvCtrlIsBootFromSPI(MV_VOID)+{+    MV_U32 satr = 0;+    satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);+    if(mvCtrlModelGet() == MV_6180_DEV_ID)+    {+        if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)+            return MV_TRUE;+        else+            return MV_FALSE;+    }+    satr = satr & MSAR_BOOT_MODE_MASK;    +    if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)+        return MV_TRUE;+    else+        return MV_FALSE;+}++MV_BOOL	  mvCtrlIsBootFromSPIUseNAND(MV_VOID)+{+    MV_U32 satr = 0;+    if(mvCtrlModelGet() == MV_6180_DEV_ID)+        return MV_FALSE;+    satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);+    satr = satr & MSAR_BOOT_MODE_MASK;+    +    if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)+        return MV_TRUE;+    else+        return MV_FALSE;+}++MV_BOOL	  mvCtrlIsBootFromNAND(MV_VOID)+{+    MV_U32 satr = 0;+    satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);+    if(mvCtrlModelGet() == MV_6180_DEV_ID)+    {+        if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)+            return MV_TRUE;+        else+            return MV_FALSE;+    }+    satr = satr & MSAR_BOOT_MODE_MASK;    +    if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))+        return MV_TRUE;+    else+        return MV_FALSE;+}++#if defined(MV_INCLUDE_CLK_PWR_CNTRL)+/*******************************************************************************+* mvCtrlPwrSaveOn - Set Power save mode+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*******************************************************************************/+MV_VOID   mvCtrlPwrSaveOn(MV_VOID)+{+	unsigned long old,temp;+	/* Disable int */+	__asm__ __volatile__("mrs %0, cpsr\n"+			     "orr %1, %0, #0xc0\n"+			     "msr cpsr_c, %1"+			     : "=r" (old), "=r" (temp)+			     :+			     : "memory");++	/* Set SoC in power save */+	MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);+	/* Wait for int */+	__asm__ __volatile__("mcr    p15, 0, r0, c7, c0, 4");++	/* Enabled int */+	__asm__ __volatile__("msr cpsr_c, %0"+			     :+			     : "r" (old)+			     : "memory");+}++++/*******************************************************************************+* mvCtrlPwrSaveOff - Go out of power save mode+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*******************************************************************************/+MV_VOID   mvCtrlPwrSaveOff(MV_VOID)+{+	unsigned long old,temp;+	/* Disable int */+	__asm__ __volatile__("mrs %0, cpsr\n"+			     "orr %1, %0, #0xc0\n"+			     "msr cpsr_c, %1"+			     : "=r" (old), "=r" (temp)+			     :+			     : "memory");++	/* Set SoC in power save */+	MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);+	/* Wait for int */+	__asm__ __volatile__("mcr    p15, 0, r0, c7, c0, 4");++	/* Enabled int */+	__asm__ __volatile__("msr cpsr_c, %0"+			     :+			     : "r" (old)+			     : "memory");+}++/*******************************************************************************+* mvCtrlPwrClckSet - Set Power State for specific Unit+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*******************************************************************************/+MV_VOID   mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)+{+	switch (unitId)+    {+#if defined(MV_INCLUDE_PEX)+	case PEX_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_GIG_ETH)+	case ETH_GIG_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));+		}+		break;+#endif+#if defined(MV_INCLUDE_INTEG_SATA)+	case SATA_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));+		}+		break;+#endif+#if defined(MV_INCLUDE_CESA)+	case CESA_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_USB)+	case USB_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_AUDIO)+	case AUDIO_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_TS)+	case TS_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_SDIO)+	case SDIO_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_TDM)+	case TDM_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);+		}+		else+		{+			MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);+		}+		break;+#endif++	default:++		break;++	}+}++/*******************************************************************************+* mvCtrlPwrClckGet - Get Power State of specific Unit+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+******************************************************************************/+MV_BOOL		mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)+{+	MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);+	MV_BOOL state = MV_TRUE;++	switch (unitId)+    {+#if defined(MV_INCLUDE_PEX)+	case PEX_UNIT_ID:+		if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;++		break;+#endif+#if defined(MV_INCLUDE_GIG_ETH)+	case ETH_GIG_UNIT_ID:+		if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_SATA)+	case SATA_UNIT_ID:+		if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_CESA)+	case CESA_UNIT_ID:+		if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_USB)+	case USB_UNIT_ID:+		if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_AUDIO)+	case AUDIO_UNIT_ID:+		if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_TS)+	case TS_UNIT_ID:+		if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_SDIO)+	case SDIO_UNIT_ID:+		if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_TDM)+	case TDM_UNIT_ID:+		if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif++	default:+		state = MV_TRUE;+		break;+	}+++	return state;	+}+/*******************************************************************************+* mvCtrlPwrMemSet - Set Power State for memory on specific Unit+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*******************************************************************************/+MV_VOID   mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)+{+	switch (unitId)+    {+#if defined(MV_INCLUDE_PEX)+	case PEX_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_GIG_ETH)+	case ETH_GIG_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));+		}+		break;+#endif+#if defined(MV_INCLUDE_INTEG_SATA)+	case SATA_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));+		}+		break;+#endif+#if defined(MV_INCLUDE_CESA)+	case CESA_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_USB)+	case USB_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_AUDIO)+	case AUDIO_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);+		}+		break;+#endif+#if defined(MV_INCLUDE_XOR)+	case XOR_UNIT_ID:+		if (enable == MV_FALSE)+		{+			MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));+		}+		else+		{+			MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));+		}+		break;+#endif+	default:++		break;++	}+}++/*******************************************************************************+* mvCtrlPwrMemGet - Get Power State of memory on specific Unit+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+******************************************************************************/+MV_BOOL		mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)+{+	MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);+	MV_BOOL state = MV_TRUE;++	switch (unitId)+    {+#if defined(MV_INCLUDE_PEX)+	case PEX_UNIT_ID:+		if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;++		break;+#endif+#if defined(MV_INCLUDE_GIG_ETH)+	case ETH_GIG_UNIT_ID:+		if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_SATA)+	case SATA_UNIT_ID:+		if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_CESA)+	case CESA_UNIT_ID:+		if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_USB)+	case USB_UNIT_ID:+		if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_AUDIO)+	case AUDIO_UNIT_ID:+		if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif+#if defined(MV_INCLUDE_XOR)+	case XOR_UNIT_ID:+		if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))+		{+			state = MV_FALSE;+		}+		else state = MV_TRUE;+		break;+#endif++	default:+		state = MV_TRUE;+		break;+	}+++	return state;	+}+#else+MV_VOID   mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}+MV_BOOL	  mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}+#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */+++/*******************************************************************************+* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+******************************************************************************/+MV_VOID   mvMPPConfigToSPI(MV_VOID)+{+	MV_U32 mppVal = 0;+	MV_U32 bootVal = 0;++    if(!mvCtrlIsBootFromSPIUseNAND())+        return;+    mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */+    bootVal = MV_REG_READ(mvCtrlMppRegGet(0));+    bootVal &= 0xffff000f;+        mppVal |= bootVal;+    +    MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);+}+++/*******************************************************************************+* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration+*+* DESCRIPTION:		+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+******************************************************************************/+MV_VOID   mvMPPConfigToDefault(MV_VOID)+{+	MV_U32 mppVal = 0;+	MV_U32 bootVal = 0;++    if(!mvCtrlIsBootFromSPIUseNAND())+        return;+    mppVal = mvBoardMppGet(0);+    bootVal = MV_REG_READ(mvCtrlMppRegGet(0));+    mppVal &= ~0xffff000f;+    bootVal &= 0xffff000f;+        mppVal |= bootVal;+    +    MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h	2010-11-09 20:28:07.742495476 +0100@@ -0,0 +1,185 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvCtrlEnvLibh+#define __INCmvCtrlEnvLibh++/* includes */+#include "mvSysHwConfig.h"+#include "mvCommon.h"+#include "mvTypes.h"+#include "mvOs.h"+#include "boardEnv/mvBoardEnvLib.h"			+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "ctrlEnv/mvCtrlEnvRegs.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"+++/* typedefs */++/* This enumerator describes the possible HW cache coherency policies the   */+/* controllers supports.                                                    */+typedef enum _mvCachePolicy+{+    NO_COHERENCY,   /* No HW cache coherency support                        */+    WT_COHERENCY,   /* HW cache coherency supported in Write Through policy */+    WB_COHERENCY    /* HW cache coherency supported in Write Back policy    */   +}MV_CACHE_POLICY;+++/* The swapping is referred to a 64-bit words (as this is the controller    */+/* internal data path width). This enumerator describes the possible        */+/* data swap types. Below is an example of the data 0x0011223344556677      */+typedef enum _mvSwapType+{+    MV_BYTE_SWAP,       /* Byte Swap                77 66 55 44 33 22 11 00 */             +    MV_NO_SWAP,         /* No swapping              00 11 22 33 44 55 66 77 */+    MV_BYTE_WORD_SWAP,  /* Both byte and word swap  33 22 11 00 77 66 55 44 */+    MV_WORD_SWAP,       /* Word swap                44 55 66 77 00 11 22 33 */+    SWAP_TYPE_MAX	/* Delimiter for this enumerator					*/+}MV_SWAP_TYPE;++/* This structure describes access rights for Access protection windows     */+/* that can be found in IDMA, XOR, Ethernet and MPSC units.                 */+/* Note that the permission enumerator coresponds to its register format.   */+/* For example, Read only premission is presented as "1" in register field. */+typedef enum _mvAccessRights+{+    	NO_ACCESS_ALLOWED = 0,  /* No access allowed            */+    	READ_ONLY         = 1,  /* Read only permission         */+	ACC_RESERVED	  = 2,	/* Reserved access right		*/+    	FULL_ACCESS       = 3,  /* Read and Write permission    */+	MAX_ACC_RIGHTS+}MV_ACCESS_RIGHTS;+++/* mcspLib.h API list */++MV_STATUS mvCtrlEnvInit(MV_VOID);+MV_U32    mvCtrlMppRegGet(MV_U32 mppGroup);++#if defined(MV_INCLUDE_PEX)+MV_U32	  mvCtrlPexMaxIfGet(MV_VOID);+#else+#define   mvCtrlPexMaxIfGet()	(0)+#endif++#define   mvCtrlPciIfMaxIfGet()	(0)++#if defined(MV_INCLUDE_GIG_ETH) +MV_U32	  mvCtrlEthMaxPortGet(MV_VOID);+#endif+#if defined(MV_INCLUDE_XOR)+MV_U32 mvCtrlXorMaxChanGet(MV_VOID);+#endif+#if defined(MV_INCLUDE_USB)+MV_U32 	  mvCtrlUsbMaxGet(MV_VOID);+#endif+#if defined(MV_INCLUDE_NAND)+MV_U32	  mvCtrlNandSupport(MV_VOID);+#endif+#if defined(MV_INCLUDE_SDIO)+MV_U32	  mvCtrlSdioSupport(MV_VOID);+#endif+#if defined(MV_INCLUDE_TS)+MV_U32	  mvCtrlTsSupport(MV_VOID);+#endif+#if defined(MV_INCLUDE_AUDIO)+MV_U32	  mvCtrlAudioSupport(MV_VOID);+#endif+#if defined(MV_INCLUDE_TDM)+MV_U32	  mvCtrlTdmSupport(MV_VOID);+#endif++MV_U16    mvCtrlModelGet(MV_VOID);+MV_U8     mvCtrlRevGet(MV_VOID);+MV_STATUS mvCtrlNameGet(char *pNameBuff);+MV_U32    mvCtrlModelRevGet(MV_VOID);+MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);+MV_VOID   mvCtrlAddrDecShow(MV_VOID);+const MV_8* mvCtrlTargetNameGet(MV_TARGET target);+MV_U32	  ctrlSizeToReg(MV_U32 size, MV_U32 alignment);+MV_U32	  ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);+MV_U32	  ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);+MV_U32	  mvCtrlSysRstLengthCounterGet(MV_VOID);+MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);+MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);++MV_VOID   mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);+MV_BOOL	  mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);+MV_VOID   mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);+MV_BOOL	  mvCtrlIsBootFromSPI(MV_VOID);+MV_BOOL	  mvCtrlIsBootFromSPIUseNAND(MV_VOID);+MV_BOOL	  mvCtrlIsBootFromNAND(MV_VOID);+#if defined(MV_INCLUDE_CLK_PWR_CNTRL)+MV_VOID   mvCtrlPwrSaveOn(MV_VOID);+MV_VOID   mvCtrlPwrSaveOff(MV_VOID);+#endif+MV_BOOL	  mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);+MV_VOID   mvMPPConfigToSPI(MV_VOID);+MV_VOID   mvMPPConfigToDefault(MV_VOID);+++#endif /* __INCmvCtrlEnvLibh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h	2010-11-09 20:28:07.772495664 +0100@@ -0,0 +1,419 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvCtrlEnvRegsh+#define __INCmvCtrlEnvRegsh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* CV Support */+#define PEX0_MEM0 	PEX0_MEM+#define PCI0_MEM0	PEX0_MEM++/* Controller revision info */+#define PCI_CLASS_CODE_AND_REVISION_ID			    0x008+#define PCCRIR_REVID_OFFS				    0		/* Revision ID */+#define PCCRIR_REVID_MASK				    (0xff << PCCRIR_REVID_OFFS)++/* Controler environment registers offsets */++/* Power Managment Control */+#define POWER_MNG_MEM_CTRL_REG			0x20118++#define PMC_GESTOPMEM_OFFS(port)		((port)? 13 : 0)+#define PMC_GESTOPMEM_MASK(port)		(1 << PMC_GESTOPMEM_OFFS(port))+#define PMC_GESTOPMEM_EN(port)			(0 << PMC_GESTOPMEM_OFFS(port))+#define PMC_GESTOPMEM_STOP(port)		(1 << PMC_GESTOPMEM_OFFS(port))++#define PMC_PEXSTOPMEM_OFFS			1+#define PMC_PEXSTOPMEM_MASK			(1 << PMC_PEXSTOPMEM_OFFS)+#define PMC_PEXSTOPMEM_EN			(0 << PMC_PEXSTOPMEM_OFFS)+#define PMC_PEXSTOPMEM_STOP			(1 << PMC_PEXSTOPMEM_OFFS)++#define PMC_USBSTOPMEM_OFFS			2+#define PMC_USBSTOPMEM_MASK			(1 << PMC_USBSTOPMEM_OFFS)+#define PMC_USBSTOPMEM_EN			(0 << PMC_USBSTOPMEM_OFFS)+#define PMC_USBSTOPMEM_STOP			(1 << PMC_USBSTOPMEM_OFFS)++#define PMC_DUNITSTOPMEM_OFFS			3+#define PMC_DUNITSTOPMEM_MASK			(1 << PMC_DUNITSTOPMEM_OFFS)+#define PMC_DUNITSTOPMEM_EN			(0 << PMC_DUNITSTOPMEM_OFFS)+#define PMC_DUNITSTOPMEM_STOP			(1 << PMC_DUNITSTOPMEM_OFFS)++#define PMC_RUNITSTOPMEM_OFFS			4+#define PMC_RUNITSTOPMEM_MASK			(1 << PMC_RUNITSTOPMEM_OFFS)+#define PMC_RUNITSTOPMEM_EN			(0 << PMC_RUNITSTOPMEM_OFFS)+#define PMC_RUNITSTOPMEM_STOP			(1 << PMC_RUNITSTOPMEM_OFFS)++#define PMC_XORSTOPMEM_OFFS(port)		(5+(port*2))+#define PMC_XORSTOPMEM_MASK(port)		(1 << PMC_XORSTOPMEM_OFFS(port))+#define PMC_XORSTOPMEM_EN(port)			(0 << PMC_XORSTOPMEM_OFFS(port))+#define PMC_XORSTOPMEM_STOP(port)		(1 << PMC_XORSTOPMEM_OFFS(port))++#define PMC_SATASTOPMEM_OFFS(port)		(6+(port*5))+#define PMC_SATASTOPMEM_MASK(port)		(1 << PMC_SATASTOPMEM_OFFS(port))+#define PMC_SATASTOPMEM_EN(port)		(0 << PMC_SATASTOPMEM_OFFS(port))+#define PMC_SATASTOPMEM_STOP(port)		(1 << PMC_SATASTOPMEM_OFFS(port))++#define PMC_SESTOPMEM_OFFS			8+#define PMC_SESTOPMEM_MASK			(1 << PMC_SESTOPMEM_OFFS)+#define PMC_SESTOPMEM_EN			(0 << PMC_SESTOPMEM_OFFS)+#define PMC_SESTOPMEM_STOP			(1 << PMC_SESTOPMEM_OFFS)++#define PMC_AUDIOSTOPMEM_OFFS			9+#define PMC_AUDIOSTOPMEM_MASK			(1 << PMC_AUDIOSTOPMEM_OFFS)+#define PMC_AUDIOSTOPMEM_EN			(0 << PMC_AUDIOSTOPMEM_OFFS)+#define PMC_AUDIOSTOPMEM_STOP			(1 << PMC_AUDIOSTOPMEM_OFFS)++#define POWER_MNG_CTRL_REG			0x2011C++#define PMC_GESTOPCLOCK_OFFS(port)		((port)? 19 : 0)+#define PMC_GESTOPCLOCK_MASK(port)		(1 << PMC_GESTOPCLOCK_OFFS(port))+#define PMC_GESTOPCLOCK_EN(port)		(1 << PMC_GESTOPCLOCK_OFFS(port))+#define PMC_GESTOPCLOCK_STOP(port)		(0 << PMC_GESTOPCLOCK_OFFS(port))++#define PMC_PEXPHYSTOPCLOCK_OFFS		1+#define PMC_PEXPHYSTOPCLOCK_MASK		(1 << PMC_PEXPHYSTOPCLOCK_OFFS)+#define PMC_PEXPHYSTOPCLOCK_EN			(1 << PMC_PEXPHYSTOPCLOCK_OFFS)+#define PMC_PEXPHYSTOPCLOCK_STOP		(0 << PMC_PEXPHYSTOPCLOCK_OFFS)++#define PMC_PEXSTOPCLOCK_OFFS			2+#define PMC_PEXSTOPCLOCK_MASK			(1 << PMC_PEXSTOPCLOCK_OFFS)+#define PMC_PEXSTOPCLOCK_EN			(1 << PMC_PEXSTOPCLOCK_OFFS)+#define PMC_PEXSTOPCLOCK_STOP			(0 << PMC_PEXSTOPCLOCK_OFFS)++#define PMC_USBSTOPCLOCK_OFFS			3+#define PMC_USBSTOPCLOCK_MASK			(1 << PMC_USBSTOPCLOCK_OFFS)+#define PMC_USBSTOPCLOCK_EN			(1 << PMC_USBSTOPCLOCK_OFFS)+#define PMC_USBSTOPCLOCK_STOP			(0 << PMC_USBSTOPCLOCK_OFFS)++#define PMC_SDIOSTOPCLOCK_OFFS			4+#define PMC_SDIOSTOPCLOCK_MASK			(1 << PMC_SDIOSTOPCLOCK_OFFS)+#define PMC_SDIOSTOPCLOCK_EN			(1 << PMC_SDIOSTOPCLOCK_OFFS)+#define PMC_SDIOSTOPCLOCK_STOP			(0 << PMC_SDIOSTOPCLOCK_OFFS)++#define PMC_TSSTOPCLOCK_OFFS			5+#define PMC_TSSTOPCLOCK_MASK			(1 << PMC_TSSTOPCLOCK_OFFS)+#define PMC_TSSTOPCLOCK_EN			(1 << PMC_TSSTOPCLOCK_OFFS)+#define PMC_TSSTOPCLOCK_STOP			(0 << PMC_TSSTOPCLOCK_OFFS)++#define PMC_AUDIOSTOPCLOCK_OFFS			9+#define PMC_AUDIOSTOPCLOCK_MASK			(1 << PMC_AUDIOSTOPCLOCK_OFFS)+#define PMC_AUDIOSTOPCLOCK_EN			(1 << PMC_AUDIOSTOPCLOCK_OFFS)+#define PMC_AUDIOSTOPCLOCK_STOP			(0 << PMC_AUDIOSTOPCLOCK_OFFS)++#define PMC_POWERSAVE_OFFS			11+#define PMC_POWERSAVE_MASK			(1 << PMC_POWERSAVE_OFFS)+#define PMC_POWERSAVE_EN			(1 << PMC_POWERSAVE_OFFS)+#define PMC_POWERSAVE_STOP			(0 << PMC_POWERSAVE_OFFS)+++++#define PMC_SATASTOPCLOCK_OFFS(port)		(14+(port))+#define PMC_SATASTOPCLOCK_MASK(port)		(1 << PMC_SATASTOPCLOCK_OFFS(port))+#define PMC_SATASTOPCLOCK_EN(port)		(1 << PMC_SATASTOPCLOCK_OFFS(port))+#define PMC_SATASTOPCLOCK_STOP(port)		(0 << PMC_SATASTOPCLOCK_OFFS(port))++#define PMC_SESTOPCLOCK_OFFS			17+#define PMC_SESTOPCLOCK_MASK			(1 << PMC_SESTOPCLOCK_OFFS)+#define PMC_SESTOPCLOCK_EN			(1 << PMC_SESTOPCLOCK_OFFS)+#define PMC_SESTOPCLOCK_STOP			(0 << PMC_SESTOPCLOCK_OFFS)++#define PMC_TDMSTOPCLOCK_OFFS			20+#define PMC_TDMSTOPCLOCK_MASK			(1 << PMC_TDMSTOPCLOCK_OFFS)+#define PMC_TDMSTOPCLOCK_EN			(1 << PMC_TDMSTOPCLOCK_OFFS)+#define PMC_TDMSTOPCLOCK_STOP			(0 << PMC_TDMSTOPCLOCK_OFFS)+++/* Controler environment registers offsets */+#define MPP_CONTROL_REG0			0x10000+#define MPP_CONTROL_REG1			0x10004+#define MPP_CONTROL_REG2			0x10008+#define MPP_CONTROL_REG3			0x1000C+#define MPP_CONTROL_REG4			0x10010+#define MPP_CONTROL_REG5			0x10014+#define MPP_CONTROL_REG6			0x10018+#define MPP_SAMPLE_AT_RESET			0x10030+#define CHIP_BOND_REG				0x10034+#define SYSRST_LENGTH_COUNTER_REG		0x10050+#define SLCR_COUNT_OFFS				0+#define SLCR_COUNT_MASK				(0x1FFFFFFF << SLCR_COUNT_OFFS)+#define SLCR_CLR_OFFS				31+#define SLCR_CLR_MASK				(1 << SLCR_CLR_OFFS)			+#define PCKG_OPT_MASK				0x3+#define MPP_OUTPUT_DRIVE_REG			0x100E0+#define MPP_RGMII0_OUTPUT_DRIVE_OFFS            7+#define MPP_3_3_RGMII0_OUTPUT_DRIVE		(0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)+#define MPP_1_8_RGMII0_OUTPUT_DRIVE		(0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)+#define MPP_RGMII1_OUTPUT_DRIVE_OFFS            15+#define MPP_3_3_RGMII1_OUTPUT_DRIVE		(0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)+#define MPP_1_8_RGMII1_OUTPUT_DRIVE		(0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)++#define MSAR_BOOT_MODE_OFFS                     12+#define MSAR_BOOT_MODE_MASK                     (0x7 << MSAR_BOOT_MODE_OFFS)+#define MSAR_BOOT_NAND_WITH_BOOTROM		        (0x5 << MSAR_BOOT_MODE_OFFS)+#define MSAR_BOOT_SPI_WITH_BOOTROM              (0x4 << MSAR_BOOT_MODE_OFFS)+#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM		(0x2 << MSAR_BOOT_MODE_OFFS)++#define MSAR_BOOT_MODE_6180(X)                  (((X & 0x3000) >> 12) | \+                                                ((X & 0x2) << 1))+#define MSAR_BOOT_SPI_WITH_BOOTROM_6180         0x1+#define MSAR_BOOT_NAND_WITH_BOOTROM_6180        0x5++#define MSAR_TCLCK_OFFS				21+#define MSAR_TCLCK_MASK				(0x1 << MSAR_TCLCK_OFFS)+#define MSAR_TCLCK_166				(0x1 << MSAR_TCLCK_OFFS)+#define MSAR_TCLCK_200				(0x0 << MSAR_TCLCK_OFFS)+++#define MSAR_CPUCLCK_EXTRACT(X)     (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \+                                    ((X & 0x18) >> 1))++#define MSAR_CPUCLCK_OFFS_6180		2+#define MSAR_CPUCLCK_MASK_6180		(0x7 << MSAR_CPUCLCK_OFFS_6180)++#define MSAR_DDRCLCK_RTIO_OFFS		5+#define MSAR_DDRCLCK_RTIO_MASK		(0xF << MSAR_DDRCLCK_RTIO_OFFS)++#define MSAR_L2CLCK_EXTRACT(X)      (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))++#ifndef MV_ASMLANGUAGE+/* CPU clock for 6281,6192  0->Resereved */+#define MV_CPU_CLCK_TBL { 	0,		0, 		0, 		0,	\+			     	600000000, 	0,		800000000,	1000000000,	\+			     	0,	 	1200000000,	0,		0,		\+			     	1500000000,	0,		0,		0}++/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */+#define MV_DDR_CLCK_RTIO_TBL	{\+	{0, 0}, {0, 0}, {2, 1}, {0, 0}, \+	{3, 1}, {0, 0}, {4, 1}, {9, 2}, \+	{5, 1}, {6, 1}, {0, 0}, {0, 0}, \+	{0, 0}, {0, 0}, {0, 0}, {0, 0} \+}++/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */+#define MV_L2_CLCK_RTIO_TBL	{\+	{0, 0}, {2, 1}, {0, 0}, {3, 1}, \+	{0, 0}, {0, 0}, {0, 0}, {0, 0} \+}++/* 6180 have different clk reset sampling 		*/+/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved 	*/+#define MV_CPU6180_DDR_L2_CLCK_TBL    { \+	{0,   		0,   		0		},\+	{0,   		0,   		0		},\+	{0,   		0,   		0		},\+	{0,   		0,   		0		},\+	{0,   		0,   		0		},\+	{600000000, 	200000000, 	300000000	},\+	{800000000, 	200000000, 	400000000	},\+	{0,   		0,   		0		}\+}++++/* These macros help units to identify a target Mbus Arbiter group */+#define MV_TARGET_IS_DRAM(target)   \+                            ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))++#define MV_TARGET_IS_PEX0(target)   \+                            ((target >= PEX0_MEM) && (target <= PEX0_IO))++#define MV_TARGET_IS_PEX1(target)   0++#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))++#define MV_TARGET_IS_DEVICE(target) \+                            ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))++#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar)   0++#define	MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \+                     (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \+                     (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\+						 & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))+++#define MV_CHANGE_BOOT_CS(target)	(((target) == DEV_BOOCS)?\+					sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \+                    MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \+                    ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\+                     >> MSAR_BOOT_MODE_OFFS)]:(target))+					+#define TCLK_TO_COUNTER_RATIO   1   /* counters running in Tclk */++#define BOOT_TARGETS_NAME_ARRAY {       \+    TBL_TERM,         	\+    TBL_TERM,         	\+    BOOT_ROM_CS,          	\+    TBL_TERM,         	\+    BOOT_ROM_CS,          	\+    BOOT_ROM_CS,          \+    TBL_TERM,         	\+    TBL_TERM           \+}++#define BOOT_TARGETS_NAME_ARRAY_6180 {       \+    TBL_TERM,         	\+    BOOT_ROM_CS,          	\+    TBL_TERM,           \+    TBL_TERM,           \+    TBL_TERM,           \+    BOOT_ROM_CS,          \+    TBL_TERM,           \+    TBL_TERM           \+}+++/* For old competability */+#define DEVICE_CS0		NFLASH_CS  +#define DEVICE_CS1  		SPI_CS +#define DEVICE_CS2  		BOOT_ROM_CS +#define DEVICE_CS3  		DEV_BOOCS+#define MV_BOOTDEVICE_INDEX   	0++#define START_DEV_CS   		DEV_CS0+#define DEV_TO_TARGET(dev)	((dev) + DEVICE_CS0)++#define PCI_IF0_MEM0		PEX0_MEM+#define PCI_IF0_IO		PEX0_IO+++/* This enumerator defines the Marvell controller target ID      */ +typedef enum _mvTargetId+{+    DRAM_TARGET_ID  = 0 ,    /* Port 0 -> DRAM interface         */+    DEV_TARGET_ID   = 1,     /* Port 1 -> Nand/SPI 		*/+    PEX0_TARGET_ID  = 4 ,    /* Port 4 -> PCI Express0 		*/+    CRYPT_TARGET_ID = 3 ,    /* Port 3 --> Crypto Engine 	*/+    SAGE_TARGET_ID = 12 ,    /* Port 12 -> SAGE Unit 	*/+    MAX_TARGETS_ID+}MV_TARGET_ID;+++/* This enumerator described the possible Controller paripheral targets.    */+/* Controller peripherals are designated memory/IO address spaces that the  */+/* controller can access. They are also refered as "targets"                */+typedef enum _mvTarget+{+    TBL_TERM = -1, 	/* none valid target, used as targets list terminator*/+    SDRAM_CS0,      	/* SDRAM chip select 0                          */  +    SDRAM_CS1,      	/* SDRAM chip select 1                          */  +    SDRAM_CS2,      	/* SDRAM chip select 2                          */  +    SDRAM_CS3,      	/* SDRAM chip select 3                          */  +    PEX0_MEM,		/* PCI Express 0 Memory				*/+    PEX0_IO,		/* PCI Express 0 IO				*/+    INTER_REGS,     	/* Internal registers                           */  +    NFLASH_CS,     	/* NFLASH_CS					*/  +    SPI_CS,     	/* SPI_CS					*/  +    BOOT_ROM_CS,        /* BOOT_ROM_CS                                  */  +    DEV_BOOCS,     	/* DEV_BOOCS					*/  +    CRYPT_ENG,      	/* Crypto Engine				*/  +#ifdef MV_INCLUDE_SAGE+    SAGE_UNIT,      	/* SAGE Unit					*/  +#endif+    MAX_TARGETS++}MV_TARGET;++#define TARGETS_DEF_ARRAY	{			\+    {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */		\+    {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */		\+    {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */		\+    {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */		\+    {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */			\+    {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */			\+    {0xFF, 0xFF           }, /* INTER_REGS */		\+    {0x2F, DEV_TARGET_ID  },  /* NFLASH_CS */		\+    {0x1E, DEV_TARGET_ID  },  /* SPI_CS */		 	\+    {0x1D, DEV_TARGET_ID  },  /* BOOT_ROM_CS */     \+    {0x1E, DEV_TARGET_ID  },  /* DEV_BOOCS */		\+    {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */        \+    {0x00, SAGE_TARGET_ID }  						\+}+++#define TARGETS_NAME_ARRAY	{	\+    "SDRAM_CS0",    /* SDRAM_CS0 */	\+    "SDRAM_CS1",    /* SDRAM_CS1 */	\+    "SDRAM_CS2",    /* SDRAM_CS2 */	\+    "SDRAM_CS3",    /* SDRAM_CS3 */	\+    "PEX0_MEM",	    /* PEX0_MEM */	\+    "PEX0_IO",	    /* PEX0_IO */	\+    "INTER_REGS",   /* INTER_REGS */	\+    "NFLASH_CS",    /* NFLASH_CS */	\+    "SPI_CS",	    /* SPI_CS */	\+    "BOOT_ROM_CS",  /* BOOT_ROM_CS */ \+    "DEV_BOOTCS",   /* DEV_BOOCS */	\+    "CRYPT_ENG",    /* CRYPT_ENG */  \+    "SAGE_UNIT"	   /* SAGE_UNIT */	\+}+#endif /* MV_ASMLANGUAGE */+++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h	2010-11-09 20:28:07.802495420 +0100@@ -0,0 +1,257 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvCtrlEnvSpech+#define __INCmvCtrlEnvSpech++#include "mvDeviceId.h"+#include "mvSysHwConfig.h"++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++#define MV_ARM_SOC+#define SOC_NAME_PREFIX			"MV88F"+++/* units base and port numbers */+#ifdef MV_ASMLANGUAGE+#define XOR_UNIT_BASE(unit)           	0x60800+#else+#define MV_XOR_REG_BASE			0x60000+#define XOR_UNIT_BASE(unit)           	((unit)? 0x60900:0x60800)+#endif++#define TDM_REG_BASE			0xD0000+#define USB_REG_BASE(dev)       	0x50000+#define AUDIO_REG_BASE  		0xA0000+#define SATA_REG_BASE           	0x80000+#define MV_CESA_REG_BASE                0x3D000+#define MV_CESA_TDMA_REG_BASE		0x30000+#define MV_SDIO_REG_BASE		0x90000+#define MV_ETH_REG_BASE(port)      	(((port) == 0) ? 0x72000 : 0x76000)+#define MV_UART_CHAN_BASE(chanNum)	(0x12000 + (chanNum * 0x100))+#define DRAM_BASE			0x0+#define CNTMR_BASE                  	0x20300+#define TWSI_SLAVE_BASE(chanNum)    	0x11000+#define PEX_IF_BASE(pexIf)      	0x40000+#define MPP_REG_BASE			0x10000+#define TSU_GLOBAL_REG_BASE             0xB4000+#define MAX_AHB_TO_MBUS_REG_BASE	0x20000++#define INTER_REGS_SIZE	 	 	_1M+/* This define describes the TWSI interrupt bit and location */+#define TWSI_CPU_MAIN_INT_CAUSE_REG		0x20200+#define TWSI0_CPU_MAIN_INT_BIT			(1<<29)+#define TWSI_SPEED				100000++#define MV_GPP_MAX_GROUP    		2+#define MV_CNTMR_MAX_COUNTER 		2+#define MV_UART_MAX_CHAN		2+#define MV_XOR_MAX_UNIT         	2+#define MV_XOR_MAX_CHAN         	4 /* total channels for all units together*/+#define MV_XOR_MAX_CHAN_PER_UNIT       	2 /* channels for units */+#define MV_SATA_MAX_CHAN	 	2++#define MV_6281_MPP_MAX_MODULE    	2+#define MV_6192_MPP_MAX_MODULE    	1+#define MV_6190_MPP_MAX_MODULE    	1+#define MV_6180_MPP_MAX_MODULE    	2+#define MV_6281_MPP_MAX_GROUP    	7+#define MV_6192_MPP_MAX_GROUP    	4+#define MV_6190_MPP_MAX_GROUP    	4+#define MV_6180_MPP_MAX_GROUP    	3++#define MV_DRAM_MAX_CS      		4++/* This define describes the maximum number of supported PCI\PCIX Interfaces*/+#define MV_PCI_MAX_IF		0+#define MV_PCI_START_IF		0++/* This define describes the maximum number of supported PEX Interfaces 	*/+#define MV_INCLUDE_PEX0+#define MV_DISABLE_PEX_DEVICE_BAR +#define MV_PEX_MAX_IF		1+#define MV_PEX_START_IF		MV_PCI_MAX_IF++/* This define describes the maximum number of supported PCI Interfaces 	*/+#define MV_PCI_IF_MAX_IF   	(MV_PEX_MAX_IF+MV_PCI_MAX_IF)++#define MV_ETH_MAX_PORTS		2+#define MV_6281_ETH_MAX_PORTS	   	2+#define MV_6192_ETH_MAX_PORTS	   	2+#define MV_6190_ETH_MAX_PORTS	   	1+#define MV_6180_ETH_MAX_PORTS	   	1++#define MV_IDMA_MAX_CHAN    		0++#define MV_USB_MAX_PORTS		1++#define MV_USB_VERSION              1+++#define MV_6281_NAND			1+#define MV_6192_NAND			1+#define MV_6190_NAND			1+#define MV_6180_NAND			0++#define MV_6281_SDIO			1+#define MV_6192_SDIO			1+#define MV_6190_SDIO			1+#define MV_6180_SDIO			1++#define MV_6281_TS			1+#define MV_6192_TS			1+#define MV_6190_TS			0+#define MV_6180_TS			0++#define MV_6281_AUDIO			1+#define MV_6192_AUDIO			1+#define MV_6190_AUDIO			0+#define MV_6180_AUDIO			1++#define MV_6281_TDM			1+#define MV_6192_TDM			1+#define MV_6190_TDM			0+#define MV_6180_TDM			0++#define MV_DEVICE_MAX_CS      		4++/* Others */+#define PEX_HOST_BUS_NUM(pciIf)		(pciIf)+#define PEX_HOST_DEV_NUM(pciIf)		0++#define PCI_IO(pciIf)		(PEX0_IO)+#define PCI_MEM(pciIf, memNum)  (PEX0_MEM0)+/* CESA version #2: One channel, 2KB SRAM, TDMA */+#if defined(MV_CESA_CHAIN_MODE_SUPPORT)+	#define MV_CESA_VERSION		 	3+#else+#define MV_CESA_VERSION		 	2+#endif+#define MV_CESA_SRAM_SIZE               2*1024+/* This define describes the maximum number of supported Ethernet ports 	*/+#define MV_ETH_VERSION 			4+#define MV_ETH_MAX_RXQ              	8+#define MV_ETH_MAX_TXQ              	8+#define MV_ETH_PORT_SGMII          	{ MV_FALSE, MV_FALSE }+/* This define describes the the support of USB 	*/+#define MV_USB_VERSION  		1++#define MV_INCLUDE_SDRAM_CS0+#define MV_INCLUDE_SDRAM_CS1+#define MV_INCLUDE_SDRAM_CS2+#define MV_INCLUDE_SDRAM_CS3++#define MV_INCLUDE_DEVICE_CS0+#define MV_INCLUDE_DEVICE_CS1+#define MV_INCLUDE_DEVICE_CS2+#define MV_INCLUDE_DEVICE_CS3++#define MPP_GROUP_1_TYPE {\+	{0, 0, 0}, /* Reserved for AUTO */ \+	{0x22220000, 0x22222222, 0x2222}, /* TDM */ \+	{0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \+	{0x33330000, 0x33003333, 0x0033}, /* RGMII */ \+	{0x33330000, 0x03333333, 0x0033}, /* GMII */ \+	{0x11110000, 0x11111111, 0x0001}, /* TS */ \+	{0x33330000, 0x33333333, 0x3333}  /* MII */ \+}++#define MPP_GROUP_2_TYPE {\+	{0, 0, 0}, /* Reserved for AUTO */ \+	{0x22220000, 0x22222222, 0x22}, /* TDM */ \+	{0x44440000, 0x00044444, 0x0}, /* AUDIO */ \+	{0, 0, 0}, /* N_A */ \+	{0, 0, 0}, /* N_A */ \+	{0x11110000, 0x11111111, 0x01}  /* TS */ \+}++#ifndef MV_ASMLANGUAGE++/* This enumerator defines the Marvell Units ID      */ +typedef enum _mvUnitId+{+    DRAM_UNIT_ID,+    PEX_UNIT_ID,+    ETH_GIG_UNIT_ID,+    USB_UNIT_ID,+    IDMA_UNIT_ID,+    XOR_UNIT_ID,+    SATA_UNIT_ID,+    TDM_UNIT_ID,+    UART_UNIT_ID,+    CESA_UNIT_ID,+    SPI_UNIT_ID,+    AUDIO_UNIT_ID,+    SDIO_UNIT_ID,+    TS_UNIT_ID,+    MAX_UNITS_ID++}MV_UNIT_ID;++#endif++#endif /* __INCmvCtrlEnvSpech */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c	2010-11-09 20:28:07.842495395 +0100@@ -0,0 +1,1048 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++/* includes */+#include "ctrlEnv/sys/mvAhbToMbus.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++#undef MV_DEBUG+/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif++/* typedefs */+++/* CPU address remap registers offsets are inconsecutive. This struct 		*/+/* describes address remap register offsets									*/+typedef struct _ahbToMbusRemapRegOffs+{+    MV_U32 lowRegOffs;		/* Low 32-bit remap register offset			*/+    MV_U32 highRegOffs;		/* High 32 bit remap register offset		*/+}AHB_TO_MBUS_REMAP_REG_OFFS;++/* locals   */+static MV_STATUS ahbToMbusRemapRegOffsGet	(MV_U32 winNum,+										AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);++/*******************************************************************************+* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !+*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK laways.+*+*******************************************************************************/+MV_STATUS mvAhbToMbusInit(void)+{+	return MV_OK;++}++/*******************************************************************************+* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window+*+* DESCRIPTION:+*       This function sets+*       address window, also known as address decode window.+*       A new address decode window is set for specified winNum address window.+*       If address decode window parameter structure enables the window,+*       the routine will also enable the winNum window, allowing CPU to access+*       the winNum window.+*+* INPUT:+*       winNum      - Windows number.+*       pAddrDecWin - CPU winNum window data structure.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_OK if CPU winNum window was set correctly, MV_ERROR in case of+*       address window overlapps with other active CPU winNum window or+*		trying to assign 36bit base address while CPU does not support that.+*       The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.+*+*******************************************************************************/+MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)+{+	MV_TARGET_ATTRIB targetAttribs;+	MV_DEC_REGS decRegs;++	/* Parameter checking   */+	if (winNum >= MAX_AHB_TO_MBUS_WINS)+	{+		mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);+		return MV_NOT_SUPPORTED;+	}+++	/* read base register*/+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));+	}+	else+	{+		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);+	}++	/* check if address is aligned to the size */+	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+	{+		mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\+				   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+				   winNum,+				   mvCtrlTargetNameGet(pAddrDecWin->target),+				   pAddrDecWin->addrWin.baseLow,+				   pAddrDecWin->addrWin.size);+		return MV_ERROR;+	}++	/* read control register*/+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));+	}++	if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+	{+		mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");+		return MV_ERROR;+	}++	/* enable\Disable */+	if (MV_TRUE == pAddrDecWin->enable)+	{+		decRegs.sizeReg |= ATMWCR_WIN_ENABLE;+	}+	else+	{+		decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;+	}++	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);++	/* set attributes */+	decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;+	decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;+	/* set target ID */+	decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;+	decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;++#if !defined(MV_RUN_FROM_FLASH)+    /* To be on the safe side we disable the window before writing the  */+    /* new values.                                                      */+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		mvAhbToMbusWinEnable(winNum,MV_FALSE);+	}+#endif++	/* 3) Write to address decode Base Address Register                   */+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);+	}+	else+	{+		MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);+	}+++	/* Internal register space have no size	*/+	/* register. Do not perform size register assigment for those targets 	*/+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		/* Write to address decode Size Register                        	*/+		MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);+	}++    return MV_OK;+}++/*******************************************************************************+* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window+*+* DESCRIPTION:+*		Get the CPU peripheral winNum address window.+*+* INPUT:+*       winNum - Peripheral winNum enumerator+*+* OUTPUT:+*       pAddrDecWin - CPU winNum window information data structure.+*+* RETURN:+*       MV_OK if winNum exist, MV_ERROR otherwise.+*+*******************************************************************************/+MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)+{+	MV_DEC_REGS decRegs;+	MV_TARGET_ATTRIB targetAttrib;+++	/* Parameter checking   */+	if (winNum >= MAX_AHB_TO_MBUS_WINS)+	{+		mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);+		return MV_NOT_SUPPORTED;+	}+++	/* Internal register space size have no size register*/+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		decRegs.sizeReg =  MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));+	}+	else+	{+		decRegs.sizeReg = 0;+	}+++	/* Read base and size	*/+	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)+	{+		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));+	}+	else+	{+		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);+	}++++	if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))+	{+		mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");+		return MV_ERROR;+	}++	if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)+	{+        pAddrDecWin->addrWin.size = INTER_REGS_SIZE;+		pAddrDecWin->target = INTER_REGS;+		pAddrDecWin->enable = MV_TRUE;++		return MV_OK;+	}+++	if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else+	{+		pAddrDecWin->enable = MV_FALSE;++	}++++	if (-1 == pAddrDecWin->addrWin.size)+	{+		return MV_ERROR;+	}++	/* attrib and targetId */+	targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>+													ATMWCR_WIN_ATTR_OFFS;+	targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>+													ATMWCR_WIN_TARGET_OFFS;++	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++	return MV_OK;+}++/*******************************************************************************+* mvAhbToMbusWinTargetGet - Get Window number associated with target+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*+*******************************************************************************/+MV_U32	  mvAhbToMbusWinTargetGet(MV_TARGET target)+{+	MV_AHB_TO_MBUS_DEC_WIN decWin;+	MV_U32 winNum;++	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);+		return 0xffffffff;+	}++	if (INTER_REGS == target)+	{+		return MV_AHB_TO_MBUS_INTREG_WIN;+	}++	for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)+	{+		if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)+			continue;++		if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)+		{+			mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");+			return 0xffffffff;++		}++		if (decWin.enable == MV_TRUE)+		{+			if (decWin.target == target)+			{+				return winNum;+			}++		}++	}++	return 0xFFFFFFFF;+++}++/*******************************************************************************+* mvAhbToMbusWinAvailGet - Get First Available window number.+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*+*******************************************************************************/+MV_U32    mvAhbToMbusWinAvailGet(MV_VOID)+{+        MV_AHB_TO_MBUS_DEC_WIN decWin;+        MV_U32 winNum;++        for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)+        {+                if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)+                        continue;++                if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)+                {+                        mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");+                        return 0xffffffff;++                }++                if (decWin.enable == MV_FALSE)+                {+			return winNum;+                }++        }++        return 0xFFFFFFFF;+}+++/*******************************************************************************+* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window+*+* DESCRIPTION:+*       This function enable/disable a CPU address decode window.+*       if parameter 'enable' == MV_TRUE the routine will enable the+*       window, thus enabling CPU accesses (before enabling the window it is+*       tested for overlapping). Otherwise, the window will be disabled.+*+* INPUT:+*       winNum - Peripheral winNum enumerator.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if protection window number was wrong, or the window+*       overlapps other winNum window.+*+*******************************************************************************/+MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)+{++	/* Parameter checking   */+	if (winNum >= MAX_AHB_TO_MBUS_WINS)+	{+		mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);+		return MV_NOT_SUPPORTED;+	}++	/* Internal registers bar can't be disable or enabled */+	if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)+	{+		return (enable ? MV_OK : MV_ERROR);+	}++    if (enable == MV_TRUE)+    {+		/* enable the window */+		MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);+    }+    else+    {   /* Disable address decode winNum window                             */+		MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);+    }++	return MV_OK;+}+++/*******************************************************************************+* mvAhbToMbusWinRemap - Set CPU remap register for address windows.+*+* DESCRIPTION:+*       After a CPU address hits one of PCI address decode windows there is an+*       option to remap the address to a different one. For example, CPU+*       executes a read from PCI winNum window address 0x1200.0000. This+*       can be modified so the address on the PCI bus would be 0x1400.0000+*       Using the PCI address remap mechanism.+*+* INPUT:+*       winNum      - Peripheral winNum enumerator. Must be a PCI winNum.+*       pAddrDecWin - CPU winNum window information data structure.+*                     Note that caller has to fill in the base field only. The+*                     size field is ignored.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if winNum is not a PCI one, MV_OK otherwise.+*+*******************************************************************************/+MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)+{+    MV_U32 baseAddr;+	AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;++    MV_U32 effectiveBaseAddress=0,+		   baseAddrValue=0,windowSizeValue=0;+++	/* Get registers offsets of given winNum 		*/+	if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))+	{+		return 0xffffffff;+	}++	/* 1) Set address remap low */+    baseAddr = pAddrWin->baseLow;++    /* Check base address aligment 					*/+	/*+	if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))+	{+        mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",+																baseAddr);+        return MV_ERROR;+	}+	*/++	/* BaseLow[31:16] => base register [31:16] 		*/+	baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;++    MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);++	MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);+++	baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));+	windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));++	baseAddrValue &= ATMWBR_BASE_MASK;+	windowSizeValue &=ATMWCR_WIN_SIZE_MASK;++   /* Start calculating the effective Base Address */+   effectiveBaseAddress = baseAddrValue ;++   /* The effective base address will be combined from the chopped (if any)+	  remap value (according to the size value and remap mechanism) and the+	  window's base address */+   effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);+   /* If the effectiveBaseAddress exceed the window boundaries return an+	  invalid value. */++   if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))+   {+		mvOsPrintf("mvAhbToMbusPciRemap: Error\n");+		return 0xffffffff;+   }++	return effectiveBaseAddress;+++}+/*******************************************************************************+* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets+*+* DESCRIPTION:+*+* INPUT:+*       target1      - CPU Interface target 1+*       target2      - CPU Interface target 2+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if targets are illigal, or if one of the targets is not+*	    associated to a valid window .+*       MV_OK otherwise.+*+*******************************************************************************/+++MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)+{+	MV_U32 winNum1,winNum2;+	MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;+	AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;+	MV_U32 remapBaseLow1=0,remapBaseLow2=0;+	MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;+++	/* Check parameters */+	if (target1 >= MAX_TARGETS)+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);+		return MV_ERROR;+	}++	if (target2 >= MAX_TARGETS)+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);+		return MV_ERROR;+	}+++    /* get window associated with this target */+	winNum1 = mvAhbToMbusWinTargetGet(target1);++	if (winNum1 == 0xffffffff)+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",+					target1,winNum1);+		return MV_ERROR;++	}++    /* get window associated with this target */+	winNum2 = mvAhbToMbusWinTargetGet(target2);++	if (winNum2 == 0xffffffff)+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",+					target2,winNum2);+		return MV_ERROR;++	}++	/* now Get original values of both Windows */+	if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",+					winNum1);+		return MV_ERROR;++	}+	if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",+					winNum2);+		return MV_ERROR;++	}+++	/* disable both windows */+	if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",+					winNum1);+		return MV_ERROR;++	}+	if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))+	{+		mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",+					winNum2);+		return MV_ERROR;++	}+++	/* now swap targets */++	/* first save winDec2 values */+	winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;+	winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;+	winDecTemp.addrWin.size = winDec2.addrWin.size;+	winDecTemp.enable = winDec2.enable;+	winDecTemp.target = winDec2.target;++	/* winDec2 = winDec1 */+	winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;+	winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;+	winDec2.addrWin.size = winDec1.addrWin.size;+	winDec2.enable = winDec1.enable;+	winDec2.target = winDec1.target;+++	/* winDec1 = winDecTemp */+	winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;+	winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;+	winDec1.addrWin.size = winDecTemp.addrWin.size;+	winDec1.enable = winDecTemp.enable;+	winDec1.target = winDecTemp.target;+++	/* now set the new values */+++    mvAhbToMbusWinSet(winNum1,&winDec1);+	mvAhbToMbusWinSet(winNum2,&winDec2);++++++	/* now we will treat the remap windows if exist */+++	/* now check if one or both windows has a remap window+	as well after the swap ! */++	/* if a window had a remap value differnt than the base value+	before the swap , then after the swap the remap value will be+	equal to the base value unless both windows has a remap windows*/++	/* first get old values */+	if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))+	{+		remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);+	    remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);++	}+	if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))+	{+		remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);+	    remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);+++	}++	/* now do the swap */+	if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))+	{+		if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))+		{+			/* Two windows has a remap !!! so swap */++			MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);+			MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);++			MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);+			MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);++++		}+		else+		{+			/* remap == base */+			MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);+			MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);++		}++	}+	else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))+	{+		/* remap == base */+		MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);+		MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);++	}++++	return MV_OK;+++}++++#if defined(MV_88F1181)++/*******************************************************************************+* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.+*+* DESCRIPTION:+*       This function sets CPU Mbus Arbiter+*+* INPUT:+*       pPizzaArbArray - A priority Structure describing 16 "pizza slices". At+*                    each clock cycle, the crossbar arbiter samples all+*                    requests and gives the bus to the next agent according+*                    to the "pizza".+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if paramers to function invalid.+*+*******************************************************************************/+MV_STATUS  mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)+{+	MV_U32 sliceNum;+	MV_U32 xbarCtrl = 0;+	MV_MBUS_ARB_TARGET xbarTarget;++	/* 1) Set crossbar control low register */+	for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)+	{+		xbarTarget = pPizzaArbArray[sliceNum];++		/* sliceNum parameter check */+		if (xbarTarget > MAX_MBUS_ARB_TARGETS)+		{+			mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",+																  xbarTarget);+			return MV_ERROR;+		}+		xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));+	}+	/* Write to crossbar control low register */+    MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);++	xbarCtrl = 0;++	/* 2) Set crossbar control high register */+	for (sliceNum = MRLR_SLICE_NUM;+		 sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;+		 sliceNum++)+	{++		xbarTarget = pPizzaArbArray[sliceNum];++		/* sliceNum parameter check */+		if (xbarTarget > MAX_MBUS_ARB_TARGETS)+		{+			mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",+																  xbarTarget);+			return MV_ERROR;+		}+		xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));+	}+	/* Write to crossbar control high register */+    MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);++	return MV_OK;+}++/*******************************************************************************+* mvMbusArbCtrlSet - Set MBus Arbiter control register+*+* DESCRIPTION:+*+* INPUT:+*       ctrl  - pointer to MV_MBUS_ARB_CTRL register+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if paramers to function invalid.+*+*******************************************************************************/+MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)+{++	if (ctrl->highPrio == MV_FALSE)+	{+		MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);+	}+	else+	{+		MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);+	}++	if (ctrl->fixedRoundRobin == MV_FALSE)+	{+		MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);+	}+	else+	{+		MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);+	}++	if (ctrl->starvEn == MV_FALSE)+	{+		MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);+	}+	else+	{+		MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);+	}++	return MV_OK;+}++/*******************************************************************************+* mvMbusArbCtrlGet - Get MBus Arbiter control register+*+* DESCRIPTION:+*+* INPUT:+*       ctrl  - pointer to MV_MBUS_ARB_CTRL register+*+* OUTPUT:+*       ctrl  - pointer to MV_MBUS_ARB_CTRL register+*+* RETURN:+*       MV_ERROR if paramers to function invalid.+*+*******************************************************************************/+MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)+{++	MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);++	if (ctrlReg & MACR_ARB_ARM_TOP)+	{+		ctrl->highPrio = MV_TRUE;+	}+	else+	{+		ctrl->highPrio = MV_FALSE;+	}++	if (ctrlReg & MACR_ARB_TARGET_FIXED)+	{+		ctrl->fixedRoundRobin = MV_TRUE;+	}+	else+	{+		ctrl->fixedRoundRobin = MV_FALSE;+	}++	if (ctrlReg & MACR_ARB_REQ_CTRL_EN)+	{+		ctrl->starvEn = MV_TRUE;+	}+	else+	{+		ctrl->starvEn = MV_FALSE;+	}+++	return MV_OK;+}++#endif  /* #if defined(MV_88F1181) */++++/*******************************************************************************+* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets+*+* DESCRIPTION:+* 		CPU to PCI address remap registers offsets are inconsecutive.+*		This function returns PCI address remap registers offsets.+*+* INPUT:+*       winNum - Address decode window number. See MV_U32 enumerator.+*+* OUTPUT:+*       None.+*+* RETURN:+*		MV_ERROR if winNum is not a PCI one.+*+*******************************************************************************/+static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,+									AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)+{+	switch (winNum)+	{+		case 0:+        case 1:+			pRemapRegs->lowRegOffs  = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);+			pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);+			break;+		case 2:+		case 3:+			if((mvCtrlModelGet() == MV_5281_DEV_ID) ||+				(mvCtrlModelGet() == MV_1281_DEV_ID) ||+				(mvCtrlModelGet() == MV_6183_DEV_ID) ||+               (mvCtrlModelGet() == MV_6183L_DEV_ID))+			{+				pRemapRegs->lowRegOffs  = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);+				pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);+				break;+			}+			else+			{+				pRemapRegs->lowRegOffs  = 0;+				pRemapRegs->highRegOffs = 0;++				DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",+							winNum));+				return MV_NO_SUCH;+			}+		default:+		{+			pRemapRegs->lowRegOffs  = 0;+			pRemapRegs->highRegOffs = 0;++			DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",+						winNum));+		   	return MV_NO_SUCH;+		}+	}++	return MV_OK;+}++/*******************************************************************************+* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.+*+* DESCRIPTION:+*		This function print the CPU address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvAhbToMbusAddDecShow(MV_VOID)+{+	MV_AHB_TO_MBUS_DEC_WIN win;+	MV_U32 winNum;+	mvOsOutput( "\n" );+	mvOsOutput( "AHB To MBUS Bridge:\n" );+	mvOsOutput( "-------------------\n" );++	for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )+	{+		memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );++		mvOsOutput( "win%d - ", winNum );++		if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )+		{+			if( win.enable )+			{+				mvOsOutput( "%s base %08x, ",+				mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );+                		mvOsOutput( "...." );+				mvSizePrint( win.addrWin.size );++				mvOsOutput( "\n" );++            }+			else+				mvOsOutput( "disable\n" );+		}+	}++}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h	2010-11-09 20:28:07.872495394 +0100@@ -0,0 +1,130 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvAhbToMbush+#define __INCmvAhbToMbush++/* includes */+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++/* defines  */++#if defined(MV_88F1181)+/* This enumerator defines the Marvell controller possible MBUS arbiter     */+/* target ports. It is used to define crossbar priority scheame (pizza)     */ +typedef enum _mvMBusArbTargetId+{+    DRAM_MBUS_ARB_TARGET = 0,    /* Port 0 -> DRAM interface         */+    TWSI_MBUS_ARB_TARGET  = 1,     /* Port 1 -> TWSI 		    */+    ARM_MBUS_ARB_TARGET   = 2,     /* Port 2 -> ARM		    */+	PEX1_MBUS_ARB_TARGET  = 3,    /* Port 3 -> PCI Express 1		    */+    PEX0_MBUS_ARB_TARGET  = 4,    /* Port 4 -> PCI Express0 		    */+	MAX_MBUS_ARB_TARGETS+}MV_MBUS_ARB_TARGET;++typedef struct _mvMBusArbCtrl+{+	MV_BOOL starvEn;+	MV_BOOL highPrio;+	MV_BOOL fixedRoundRobin;++}MV_MBUS_ARB_CTRL;++#endif /* #if defined(MV_88F1181) */++typedef struct _mvAhbtoMbusDecWin+{+	MV_TARGET	  target;+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */++}MV_AHB_TO_MBUS_DEC_WIN;++/* mvAhbToMbus.h API list */++MV_STATUS mvAhbToMbusInit(MV_VOID);+MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);+MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);+MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);+MV_U32    mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);+MV_U32	  mvAhbToMbusWinTargetGet(MV_TARGET target);+MV_U32    mvAhbToMbusWinAvailGet(MV_VOID);+MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);++#if defined(MV_88F1181)++MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);+MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);+MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);++#endif /* #if defined(MV_88F1181) */+++MV_VOID   mvAhbToMbusAddDecShow(MV_VOID);+++#endif /* __INCmvAhbToMbush */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h	2010-11-09 20:28:07.902495495 +0100@@ -0,0 +1,143 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvAhbToMbusRegsh+#define __INCmvAhbToMbusRegsh++/******************************/+/* ARM Address Map Registers  */+/******************************/++#define MAX_AHB_TO_MBUS_WINS	9+#define MV_AHB_TO_MBUS_INTREG_WIN	8+++#define AHB_TO_MBUS_WIN_CTRL_REG(winNum)		(0x20000 + (winNum)*0x10)+#define AHB_TO_MBUS_WIN_BASE_REG(winNum)		(0x20004 + (winNum)*0x10)+#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum)	(0x20008 + (winNum)*0x10)+#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum)	(0x2000C + (winNum)*0x10)+#define AHB_TO_MBUS_WIN_INTEREG_REG				 0x20080++/* Window Control Register      */+/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/+#define ATMWCR_WIN_ENABLE					BIT0	/* Window Enable */++#define ATMWCR_WIN_TARGET_OFFS			4 /* The target interface associated +											 with this window*/+#define ATMWCR_WIN_TARGET_MASK			(0xf << ATMWCR_WIN_TARGET_OFFS)++#define ATMWCR_WIN_ATTR_OFFS				8 /* The target interface attributes+											 Associated with this window */+#define ATMWCR_WIN_ATTR_MASK				(0xff << ATMWCR_WIN_ATTR_OFFS)++											 +/*+Used with the Base register to set the address window size and location+Must be programed from LSB to MSB as sequence of 1’s followed+by sequence of 0’s. The number of 1’s specifies the size of the window+in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).++NOTE: A value of 0x0 specifies 64KB size.+*/+#define ATMWCR_WIN_SIZE_OFFS				16 /* Window Size */+#define ATMWCR_WIN_SIZE_MASK				(0xffff << ATMWCR_WIN_SIZE_OFFS)+#define ATMWCR_WIN_SIZE_ALIGNMENT			0x10000++/*  Window Base Register     */+/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */++/*+Used with the size field to set the address window size and location.+Corresponds to transaction address[31:16]+*/+#define ATMWBR_BASE_OFFS					16 /* Base Address */+#define ATMWBR_BASE_MASK					(0xffff << 	ATMWBR_BASE_OFFS)+#define ATMWBR_BASE_ALIGNMENT				0x10000++/*  Window Remap Low Register   */+/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */++/*+Used with the size field to specifies address bits[31:0] to be driven to+the target interface.:+target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])+*/+#define ATMWRLR_REMAP_LOW_OFFS			16 /* Remap Address */+#define ATMWRLR_REMAP_LOW_MASK			(0xffff << ATMWRLR_REMAP_LOW_OFFS)+#define ATMWRLR_REMAP_LOW_ALIGNMENT		0x10000++/* Window Remap High Register   */+/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */++/*+Specifies address bits[63:32] to be driven to the target interface.+target_addr[63:32] = (RemapHigh[31:0]+*/+#define ATMWRHR_REMAP_HIGH_OFFS			0 /* Remap Address */+#define ATMWRHR_REMAP_HIGH_MASK			(0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)+++#endif /* __INCmvAhbToMbusRegsh */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c	2010-11-09 20:28:07.942495425 +0100@@ -0,0 +1,1036 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++/* includes */+#include "ctrlEnv/sys/mvCpuIf.h"+#include "ctrlEnv/sys/mvAhbToMbusRegs.h"+#include "cpu/mvCpu.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "mvSysHwConfig.h"+#include "mvSysDram.h"++/*#define MV_DEBUG*/+/* defines  */++#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif++/* locals   */+/* static functions */+static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);++MV_TARGET * sampleAtResetTargetArray;+MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;+MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;+/*******************************************************************************+* mvCpuIfInit - Initialize Controller CPU interface+*+* DESCRIPTION:+*       This function initialize Controller CPU interface:+*       1. Set CPU interface configuration registers.+*       2. Set CPU master Pizza arbiter control according to static+*          configuration described in configuration file.+*       3. Opens CPU address decode windows. DRAM windows are assumed to be+*		   already set (auto detection).+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)+{+	MV_U32 regVal;+	MV_TARGET target;+	MV_ADDR_WIN addrWin;++	if (cpuAddrWinMap == NULL)+	{+		DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));+		return MV_ERROR;+	}++    /*Initialize the boot target array according to device type*/+    if(mvCtrlModelGet() == MV_6180_DEV_ID)+        sampleAtResetTargetArray = sampleAtResetTargetArray6180P;+    else+        sampleAtResetTargetArray = sampleAtResetTargetArrayP;++	/* Set ARM Configuration register */+	regVal  = MV_REG_READ(CPU_CONFIG_REG);+	regVal &= ~CPU_CONFIG_DEFAULT_MASK;+	regVal |= CPU_CONFIG_DEFAULT;+	MV_REG_WRITE(CPU_CONFIG_REG,regVal);++	/* First disable all CPU target windows  */+	for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)+    	{+		if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))+		{+			continue;+		}++#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)+		/* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */+		if (MV_TARGET_IS_PCI(target))+		{+			continue;+		}+#endif++#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)+		/* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */+		if (MV_TARGET_IS_PEX(target))+		{+			continue;+		}+#endif+#if defined(MV_RUN_FROM_FLASH)+        	/* Don't disable the boot device.                               */+		if (target == DEV_BOOCS)+		{+			continue;+		}+#endif /* MV_RUN_FROM_FLASH */+		mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);+	}++#if defined(MV_RUN_FROM_FLASH)+    	/* Resize the bootcs windows before other windows, because this     */+    	/* window is enabled and will cause an overlap if not resized.      */+	target = DEV_BOOCS;++	if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))+	{+		DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));+		return MV_ERROR;+	}++	addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;+	addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;+	if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))+	{+		DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",+					  cpuAddrWinMap[target].winNum));+	}++#endif /* MV_RUN_FROM_FLASH */++	/* Go through all targets in user table until table terminator			*/+	for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)+    	{++#if defined(MV_RUN_FROM_FLASH)+	if (target == DEV_BOOCS)+	{+		continue;+	}+#endif /* MV_RUN_FROM_FLASH */++	/* if DRAM auto sizing is used do not initialized DRAM target windows, 	*/+	/* assuming this already has been done earlier.							*/+#ifdef	MV_DRAM_AUTO_SIZE+		if (MV_TARGET_IS_DRAM(target))+		{+			continue;+		}+#endif++#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)+		/* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */+		if (MV_TARGET_IS_PCI(target))+		{+			continue;+		}+#endif++#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)+		/* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */+		if (MV_TARGET_IS_PEX(target))+		{+			continue;+		}+#endif+	/* If the target attribute is the same as the boot device attribute */+	/* then it's stays disable */+		if (MV_TARGET_IS_AS_BOOT(target))+		{+			continue;+		}++		if((0 == cpuAddrWinMap[target].addrWin.size) ||+		   (DIS == cpuAddrWinMap[target].enable))++		{+			if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))+			{+				DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));+				return MV_ERROR;+			}++		}+		else+		{+			if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))+			{+				DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));+				return MV_ERROR;+			}++			addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;+			addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;+			if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))+			{+				DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",+							  cpuAddrWinMap[target].winNum));+			}+++		}+    }++	return MV_OK;+++}+++/*******************************************************************************+* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)+*       address window, also known as address decode window.+*       A new address decode window is set for specified target address window.+*       If address decode window parameter structure enables the window,+*       the routine will also enable the target window, allowing CPU to access+*       the target window.+*+* INPUT:+*       target      - Peripheral target enumerator.+*       pAddrDecWin - CPU target window data structure.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_OK if CPU target window was set correctly, MV_ERROR in case of+*       address window overlapps with other active CPU target window or+*		trying to assign 36bit base address while CPU does not support that.+*       The function returns MV_NOT_SUPPORTED, if the target is unsupported.+*+*******************************************************************************/+MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)+{+	MV_AHB_TO_MBUS_DEC_WIN decWin;+	MV_U32 existingWinNum;+	MV_DRAM_DEC_WIN addrDecWin;++	target = MV_CHANGE_BOOT_CS(target);++	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);+		return MV_ERROR;+	}++    	/* 2) Check if the requested window overlaps with current windows		*/+    	if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))+	{+        	mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);+		return MV_BAD_PARAM;+	}++	if (MV_TARGET_IS_DRAM(target))+	{+		/* copy relevant data to MV_DRAM_DEC_WIN structure */+		addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;+		addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;+		addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;+		addrDecWin.enable = pAddrDecWin->enable;+++		if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);+		{+			mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");+			return MV_ERROR;+		}++	}+	else+	{+		/* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */+		decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;+		decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;+		decWin.addrWin.size = pAddrDecWin->addrWin.size;+		decWin.enable = pAddrDecWin->enable;+		decWin.target = target;++		existingWinNum = mvAhbToMbusWinTargetGet(target);++		/* check if there is already another Window configured+		for this target */+		if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&+			(existingWinNum != pAddrDecWin->winNum))+		{+			/* if we want to enable the new winow number+			passed by the user , then the old one should+			be disabled */+			if (MV_TRUE == pAddrDecWin->enable)+			{+				/* be sure it is disabled */+				mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);+			}+		}++        if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)+		{+			mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");+			return MV_ERROR;+		}++	}++    return MV_OK;+}++/*******************************************************************************+* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window+*+* DESCRIPTION:+*		Get the CPU peripheral target address window.+*+* INPUT:+*       target - Peripheral target enumerator+*+* OUTPUT:+*       pAddrDecWin - CPU target window information data structure.+*+* RETURN:+*       MV_OK if target exist, MV_ERROR otherwise.+*+*******************************************************************************/+MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)+{++	MV_U32 winNum=0xffffffff;+	MV_AHB_TO_MBUS_DEC_WIN decWin;+	MV_DRAM_DEC_WIN addrDecWin;++	target = MV_CHANGE_BOOT_CS(target);++	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);+		return MV_ERROR;+	}++	if (MV_TARGET_IS_DRAM(target))+	{+		if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)+		{+			mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",+					   target);+			return MV_ERROR;+		}++		/* copy relevant data to MV_CPU_DEC_WIN structure */+		pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;+		pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;+		pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;+		pAddrDecWin->enable = addrDecWin.enable;+		pAddrDecWin->winNum = 0xffffffff;++	}+	else+	{+		/* get the Window number associated with this target */++		winNum = mvAhbToMbusWinTargetGet(target);+		if (winNum >= MAX_AHB_TO_MBUS_WINS)+		{+			return MV_NO_SUCH;++		}++		if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)+		{+			mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",+					   __FUNCTION__, winNum);+			return MV_ERROR;++		}++		/* copy relevant data to MV_CPU_DEC_WIN structure */+		pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;+		pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;+		pAddrDecWin->addrWin.size = decWin.addrWin.size;+		pAddrDecWin->enable = decWin.enable;+		pAddrDecWin->winNum = winNum;++	}+++++	return MV_OK;+}+++/*******************************************************************************+* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window+*+* DESCRIPTION:+*       This function enable/disable a CPU address decode window.+*       if parameter 'enable' == MV_TRUE the routine will enable the+*       window, thus enabling CPU accesses (before enabling the window it is+*       tested for overlapping). Otherwise, the window will be disabled.+*+* INPUT:+*       target - Peripheral target enumerator.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if protection window number was wrong, or the window+*       overlapps other target window.+*+*******************************************************************************/+MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)+{+	MV_U32 winNum, temp;+	MV_CPU_DEC_WIN addrDecWin;++	target = MV_CHANGE_BOOT_CS(target);+	+	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);+		return MV_ERROR;+	}++	/* get the window and check if it exist */+	temp = mvCpuIfTargetWinGet(target, &addrDecWin);+	if (MV_NO_SUCH == temp)+	{+		return (enable? MV_ERROR: MV_OK);+	}+	else if( MV_OK != temp)+	{+		mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);+		return MV_ERROR;+	}+++	/* check overlap */++	if (MV_TRUE == enable)+	{+		if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))+		{+			DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));+			return MV_ERROR;+		}++	}+++	if (MV_TARGET_IS_DRAM(target))+	{+		if (mvDramIfWinEnable(target , enable) != MV_OK)+		{+			mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");+			return MV_ERROR;++		}++	}+	else+	{+		/* get the Window number associated with this target */++		winNum = mvAhbToMbusWinTargetGet(target);++		if (winNum >= MAX_AHB_TO_MBUS_WINS)+		{+			return (enable? MV_ERROR: MV_OK);+		}++		if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)+		{+			mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",+					   winNum);+			return MV_ERROR;++		}++	}++	return MV_OK;+}+++/*******************************************************************************+* mvCpuIfTargetWinSizeGet - Get CPU target address window size+*+* DESCRIPTION:+*		Get the size of CPU-to-peripheral target window.+*+* INPUT:+*       target - Peripheral target enumerator+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit size. Function also returns '0' if window is closed.+*		Function returns 0xFFFFFFFF in case of an error.+*+*******************************************************************************/+MV_U32    mvCpuIfTargetWinSizeGet(MV_TARGET target)+{+	MV_CPU_DEC_WIN addrDecWin;++	target = MV_CHANGE_BOOT_CS(target);++	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);+		return 0;+	}++    /* Get the winNum window */+	if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))+	{+		mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",+                                                                        target);+		return 0;+	}++	/* Check if window is enabled   */+	if (addrDecWin.enable == MV_TRUE)+    {+		return (addrDecWin.addrWin.size);+    }+    else+    {+        return 0;		/* Window disabled. return 0 */+    }+}++/*******************************************************************************+* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low+*+* DESCRIPTION:+*       CPU-to-peripheral target address window base is constructed of+*       two parts: Low and high.+*		This function gets the CPU peripheral target low base address.+*+* INPUT:+*       target - Peripheral target enumerator+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit low base address.+*+*******************************************************************************/+MV_U32   mvCpuIfTargetWinBaseLowGet(MV_TARGET target)+{+	MV_CPU_DEC_WIN addrDecWin;++	target = MV_CHANGE_BOOT_CS(target);++	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);+		return 0xffffffff;+	}++    /* Get the target window */+	if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))+	{+		mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",+                                                                        target);+		return 0xffffffff;+	}++	if (MV_FALSE == addrDecWin.enable)+	{+		return 0xffffffff;+	}+	return (addrDecWin.addrWin.baseLow);+}++/*******************************************************************************+* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high+*+* DESCRIPTION:+*       CPU-to-peripheral target address window base is constructed of+*       two parts: Low and high.+*		This function gets the CPU peripheral target high base address.+*+* INPUT:+*       target - Peripheral target enumerator+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit high base address.+*+*******************************************************************************/+MV_U32    mvCpuIfTargetWinBaseHighGet(MV_TARGET target)+{+	MV_CPU_DEC_WIN addrDecWin;++	target = MV_CHANGE_BOOT_CS(target);++	/* Check parameters */+	if (target >= MAX_TARGETS)+	{+		mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);+		return 0xffffffff;+	}++    /* Get the target window */+	if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))+	{+		mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",+                                                                        target);+		return 0xffffffff;+	}++	if (MV_FALSE == addrDecWin.enable)+	{+		return 0;+	}++	return (addrDecWin.addrWin.baseHigh);+}++#if defined(MV_INCLUDE_PEX)+/*******************************************************************************+* mvCpuIfPexRemap - Set CPU remap register for address windows.+*+* DESCRIPTION:+*+* INPUT:+*       pexTarget   - Peripheral target enumerator. Must be a PEX target.+*       pAddrDecWin - CPU target window information data structure.+*                     Note that caller has to fill in the base field only. The+*                     size field is ignored.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if target is not a PEX one, MV_OK otherwise.+*+*******************************************************************************/+MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)+{+	MV_U32 winNum;++	/* Check parameters */++	if (mvCtrlPexMaxIfGet() > 1)+	{+		if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))+		{+			mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);+			return 0xffffffff;+		}++	}+	else+	{+		if (!MV_TARGET_IS_PEX0(pexTarget))+		{+			mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);+			return 0xffffffff;+		}++	}++	/* get the Window number associated with this target */+	winNum = mvAhbToMbusWinTargetGet(pexTarget);++	if (winNum >= MAX_AHB_TO_MBUS_WINS)+	{+		mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");+		return 0xffffffff;++	}++	return mvAhbToMbusWinRemap(winNum , pAddrDecWin);+}++#endif++#if defined(MV_INCLUDE_PCI)+/*******************************************************************************+* mvCpuIfPciRemap - Set CPU remap register for address windows.+*+* DESCRIPTION:+*+* INPUT:+*       pciTarget   - Peripheral target enumerator. Must be a PCI target.+*       pAddrDecWin - CPU target window information data structure.+*                     Note that caller has to fill in the base field only. The+*                     size field is ignored.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if target is not a PCI one, MV_OK otherwise.+*+*******************************************************************************/+MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)+{+	MV_U32 winNum;++	/* Check parameters */+	if (!MV_TARGET_IS_PCI(pciTarget))+	{+		mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);+		return 0xffffffff;+	}++	/* get the Window number associated with this target */+	winNum = mvAhbToMbusWinTargetGet(pciTarget);++	if (winNum >= MAX_AHB_TO_MBUS_WINS)+	{+		mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");+		return 0xffffffff;++	}++	return mvAhbToMbusWinRemap(winNum , pAddrDecWin);+}+#endif /* MV_INCLUDE_PCI */+++/*******************************************************************************+* mvCpuIfPciIfRemap - Set CPU remap register for address windows.+*+* DESCRIPTION:+*+* INPUT:+*       pciTarget   - Peripheral target enumerator. Must be a PCI target.+*       pAddrDecWin - CPU target window information data structure.+*                     Note that caller has to fill in the base field only. The+*                     size field is ignored.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if target is not a PCI one, MV_OK otherwise.+*+*******************************************************************************/+MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)+{+#if defined(MV_INCLUDE_PEX)+	if (MV_TARGET_IS_PEX(pciIfTarget))+	{+		return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);+	}+#endif+#if defined(MV_INCLUDE_PCI)++	if (MV_TARGET_IS_PCI(pciIfTarget))+	{+		return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);+	}+#endif+	return 0;+}++++/*******************************************************************************+* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address+*+* DESCRIPTION:+*+* INPUT:+*       baseAddress -  base address to be checked+*+* OUTPUT:+*       None.+*+* RETURN:+*       the target number that baseAddress belongs to or MAX_TARGETS is not+*       found+*+*******************************************************************************/++MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)+{+	MV_CPU_DEC_WIN win;+	MV_U32 target;++	for( target = 0; target < MAX_TARGETS; target++ )+	{+		if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )+		{+			if( win.enable )+			{+				if ((baseAddress >= win.addrWin.baseLow) &&+					(baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;+            }+		}+		else return MAX_TARGETS;++	}++	return target;+}+/*******************************************************************************+* cpuTargetWinOverlap - Detect CPU address decode windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviur is expected in case CPU address decode+*       windows overlapps.+*       This function detects CPU address decode windows overlapping of a+*       specified target. The function does not check the target itself for+*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       target      - Peripheral target enumerator.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlaps current address+*       decode map, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)+{+    MV_U32 			targetNum;+    MV_CPU_DEC_WIN 	addrDecWin;+	MV_STATUS		status;+++	for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)+    {+#if defined(MV_RUN_FROM_FLASH)+		if(MV_TARGET_IS_AS_BOOT(target))+		{+			if (MV_CHANGE_BOOT_CS(targetNum) == target)+				continue;+		}+#endif /* MV_RUN_FROM_FLASH */++		/* don't check our target or illegal targets */+        if (targetNum == target)+        {+            continue;+        }++		/* Get window parameters 	*/+		status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);+        if(MV_NO_SUCH == status)+        {+            continue;+        }+		if(MV_OK != status)+		{+			DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));+            return MV_TRUE;+		}++		/* Do not check disabled windows	*/+		if (MV_FALSE == addrDecWin.enable)+		{+			continue;+		}++        if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))+		{+			DB(mvOsPrintf(+			"cpuTargetWinOverlap: Required target %d overlap current %d\n",+								target, targetNum));+			return MV_TRUE;+		}+    }++	return MV_FALSE;++}++/*******************************************************************************+* mvCpuIfAddDecShow - Print the CPU address decode map.+*+* DESCRIPTION:+*		This function print the CPU address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvCpuIfAddDecShow(MV_VOID)+{+	MV_CPU_DEC_WIN win;+	MV_U32 target;+	mvOsOutput( "\n" );+	mvOsOutput( "CPU Interface\n" );+	mvOsOutput( "-------------\n" );++	for( target = 0; target < MAX_TARGETS; target++ )+	{++		memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );++		mvOsOutput( "%s ",mvCtrlTargetNameGet(target));+		mvOsOutput( "...." );++		if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )+		{+			if( win.enable )+			{+				mvOsOutput( "base %08x, ", win.addrWin.baseLow );+				mvSizePrint( win.addrWin.size );+				mvOsOutput( "\n" );++            }+			else+				mvOsOutput( "disable\n" );+		}+		else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )+		{+				mvOsOutput( "no such\n" );+		}+	}+}++/*******************************************************************************+* mvCpuIfEnablePex - Enable PCI Express.+*+* DESCRIPTION:+*		This function Enable PCI Express.+*+* INPUT:+*       pexIf   -  PEX interface number.+*       pexType -  MV_PEX_ROOT_COMPLEX - root complex device+*		   MV_PEX_END_POINT - end point device+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+#if defined(MV_INCLUDE_PEX)+MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)+{+	/* Set pex mode incase S@R not exist */+	if( pexType == MV_PEX_END_POINT)+	{+		MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);+		/* Change pex mode in capability reg */+		MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);+		MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);++	}+	else+	{	+		MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);+	}++	/* CPU config register Pex enable */+	MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);+}+#endif++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h	2010-11-09 20:28:07.982495689 +0100@@ -0,0 +1,120 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvCpuIfh+#define __INCmvCpuIfh++/* includes */+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/sys/mvCpuIfRegs.h"+#include "ctrlEnv/sys/mvAhbToMbus.h"+#include "ddr2/mvDramIf.h"+#include "ctrlEnv/sys/mvSysDram.h"+#if defined(MV_INCLUDE_PEX)+#include "pex/mvPex.h"+#endif++/* defines  */++/* typedefs */+/* This structure describes CPU interface address decode window               */+typedef struct _mvCpuIfDecWin +{+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_U32		  winNum;	  /* Window Number in the AHB To Mbus bridge */+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */++}MV_CPU_DEC_WIN;++++/* mvCpuIfLib.h API list */++/* mvCpuIfLib.h API list */++MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);+MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);+MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);+MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);+MV_U32    mvCpuIfTargetWinSizeGet(MV_TARGET target);+MV_U32    mvCpuIfTargetWinBaseLowGet(MV_TARGET target);+MV_U32    mvCpuIfTargetWinBaseHighGet(MV_TARGET target);+MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);+#if defined(MV_INCLUDE_PEX)+MV_U32    mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);+MV_VOID   mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);+#endif+#if defined(MV_INCLUDE_PCI)+MV_U32    mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);+#endif                                               +MV_U32 	  mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);++MV_VOID   mvCpuIfAddDecShow(MV_VOID);++#if defined(MV88F6281)+MV_STATUS mvCpuIfBridgeReorderWAInit(void);+#endif++#endif /* __INCmvCpuIfh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h	2010-11-09 20:28:08.012495399 +0100@@ -0,0 +1,304 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvCpuIfRegsh+#define __INCmvCpuIfRegsh++/****************************************/+/* ARM Control and Status Registers Map */+/****************************************/++#define CPU_CONFIG_REG				0x20100+#define CPU_CTRL_STAT_REG			0x20104+#define CPU_RSTOUTN_MASK_REG			0x20108+#define CPU_SYS_SOFT_RST_REG			0x2010C+#define CPU_AHB_MBUS_CAUSE_INT_REG		0x20110+#define CPU_AHB_MBUS_MASK_INT_REG		0x20114+#define CPU_FTDLL_CONFIG_REG			0x20120+#define CPU_L2_CONFIG_REG			0x20128++++/* ARM Configuration register */+/* CPU_CONFIG_REG (CCR) */+++/* Reset vector location */+#define CCR_VEC_INIT_LOC_OFFS			1+#define CCR_VEC_INIT_LOC_MASK			BIT1+/* reset at 0x00000000 */+#define CCR_VEC_INIT_LOC_0000			(0 << CCR_VEC_INIT_LOC_OFFS)+/* reset at 0xFFFF0000 */+#define CCR_VEC_INIT_LOC_FF00			(1 << CCR_VEC_INIT_LOC_OFFS)+++#define CCR_AHB_ERROR_PROP_OFFS			2+#define CCR_AHB_ERROR_PROP_MASK			BIT2+/* Erros are not propogated to AHB */+#define CCR_AHB_ERROR_PROP_NO_INDICATE		(0 << CCR_AHB_ERROR_PROP_OFFS)+/* Erros are propogated to AHB */+#define CCR_AHB_ERROR_PROP_INDICATE		(1 << CCR_AHB_ERROR_PROP_OFFS)+++#define CCR_ENDIAN_INIT_OFFS			3+#define CCR_ENDIAN_INIT_MASK			BIT3+#define CCR_ENDIAN_INIT_LITTLE			(0 << CCR_ENDIAN_INIT_OFFS)+#define CCR_ENDIAN_INIT_BIG			(1 << CCR_ENDIAN_INIT_OFFS)+++#define CCR_INCR_EN_OFFS			4+#define CCR_INCR_EN_MASK			BIT4+#define CCR_INCR_EN				BIT4+++#define CCR_NCB_BLOCKING_OFFS			5			+#define CCR_NCB_BLOCKING_MASK			(1 << CCR_NCB_BLOCKING_OFFS)+#define CCR_NCB_BLOCKING_NON			(0 << CCR_NCB_BLOCKING_OFFS)+#define CCR_NCB_BLOCKING_EN			(1 << CCR_NCB_BLOCKING_OFFS)++#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS		8+#define CCR_CPU_2_MBUSL_TICK_DRV_MASK		(0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)+#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS		12+#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK		(0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)+#define CCR_ICACH_PREF_BUF_ENABLE		BIT16+#define CCR_DCACH_PREF_BUF_ENABLE		BIT17++/* Ratio options for CPU to DDR for 6281/6192/6190 */+#define CPU_2_DDR_CLK_1x3	    4+#define CPU_2_DDR_CLK_1x4	    6++/* Ratio options for CPU to DDR for 6281 only */+#define CPU_2_DDR_CLK_2x9	    7+#define CPU_2_DDR_CLK_1x5	    8+#define CPU_2_DDR_CLK_1x6	    9++/* Ratio options for CPU to DDR for 6180 only */+#define CPU_2_DDR_CLK_1x3_1	    0x5+#define CPU_2_DDR_CLK_1x4_1	    0x6++/* Default values for CPU to Mbus-L DDR Interface Tick Driver and 	*/+/* CPU to Mbus-L Tick Sample fields in CPU config register		*/++#define TICK_DRV_1x1	0+#define TICK_DRV_1x2	0+#define TICK_DRV_1x3	1+#define TICK_DRV_1x4	2+#define TICK_SMPL_1x1	0+#define TICK_SMPL_1x2	1+#define TICK_SMPL_1x3	0+#define TICK_SMPL_1x4	0++#define CPU_2_MBUSL_DDR_CLK_1x2						\+		 ((TICK_DRV_1x2  << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | 	\+		  (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))+#define CPU_2_MBUSL_DDR_CLK_1x3						\+		 ((TICK_DRV_1x3  << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | 	\+		  (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))+#define CPU_2_MBUSL_DDR_CLK_1x4						\+		 ((TICK_DRV_1x4  << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | 	\+		  (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))++/* ARM Control and Status register */+/* CPU_CTRL_STAT_REG (CCSR) */+++/*+This is used to block PCI express\PCI from access Socrates/Feroceon GP+while ARM boot is still in progress+*/++#define CCSR_PCI_ACCESS_OFFS			0+#define CCSR_PCI_ACCESS_MASK			BIT0+#define CCSR_PCI_ACCESS_ENABLE			(0 << CCSR_PCI_ACCESS_OFFS)+#define CCSR_PCI_ACCESS_DISBALE			(1 << CCSR_PCI_ACCESS_OFFS)++#define CCSR_ARM_RESET				BIT1+#define CCSR_SELF_INT				BIT2+#define CCSR_BIG_ENDIAN				BIT15+++/* RSTOUTn Mask Register */+/* CPU_RSTOUTN_MASK_REG (CRMR) */++#define CRMR_PEX_RST_OUT_OFFS			0+#define CRMR_PEX_RST_OUT_MASK			BIT0+#define CRMR_PEX_RST_OUT_ENABLE			(1 << CRMR_PEX_RST_OUT_OFFS)+#define CRMR_PEX_RST_OUT_DISABLE		(0 << CRMR_PEX_RST_OUT_OFFS)++#define CRMR_WD_RST_OUT_OFFS			1+#define CRMR_WD_RST_OUT_MASK			BIT1+#define CRMR_WD_RST_OUT_ENABLE			(1 << CRMR_WD_RST_OUT_OFFS)+#define CRMR_WD_RST_OUT_DISBALE			(0 << CRMR_WD_RST_OUT_OFFS)			++#define CRMR_SOFT_RST_OUT_OFFS			2+#define CRMR_SOFT_RST_OUT_MASK			BIT2+#define CRMR_SOFT_RST_OUT_ENABLE		(1 << CRMR_SOFT_RST_OUT_OFFS)+#define CRMR_SOFT_RST_OUT_DISBALE		(0 << CRMR_SOFT_RST_OUT_OFFS)++/* System Software Reset Register */+/* CPU_SYS_SOFT_RST_REG (CSSRR) */++#define CSSRR_SYSTEM_SOFT_RST			BIT0++/* AHB to Mbus Bridge Interrupt Cause Register*/+/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */++#define CAMCIR_ARM_SELF_INT			BIT0+#define CAMCIR_ARM_TIMER0_INT_REQ		BIT1+#define CAMCIR_ARM_TIMER1_INT_REQ		BIT2+#define CAMCIR_ARM_WD_TIMER_INT_REQ		BIT3+++/* AHB to Mbus Bridge Interrupt Mask Register*/+/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */++#define CAMCIR_ARM_SELF_INT_OFFS		0+#define CAMCIR_ARM_SELF_INT_MASK		BIT0+#define CAMCIR_ARM_SELF_INT_EN			(1 << CAMCIR_ARM_SELF_INT_OFFS)+#define CAMCIR_ARM_SELF_INT_DIS			(0 << CAMCIR_ARM_SELF_INT_OFFS)+++#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS		1+#define CAMCIR_ARM_TIMER0_INT_REQ_MASK		BIT1+#define CAMCIR_ARM_TIMER0_INT_REQ_EN		(1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS) +#define CAMCIR_ARM_TIMER0_INT_REQ_DIS		(0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)++#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS		2+#define CAMCIR_ARM_TIMER1_INT_REQ_MASK		BIT2+#define CAMCIR_ARM_TIMER1_INT_REQ_EN		(1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS) +#define CAMCIR_ARM_TIMER1_INT_REQ_DIS		(0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS) ++#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 	3+#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK 	BIT3+#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN	 	(1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS) +#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS	 	(0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS) ++/* CPU FTDLL Config register (CFCR) fields */+#define CFCR_FTDLL_ICACHE_TAG_OFFS		0+#define CFCR_FTDLL_ICACHE_TAG_MASK		(0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)+#define CFCR_FTDLL_DCACHE_TAG_OFFS		8+#define CFCR_FTDLL_DCACHE_TAG_MASK		(0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)+#define CFCR_FTDLL_OVERWRITE_ENABLE		(1 << 15)+/* For Orion 2 D2 only */+#define CFCR_MRVL_CPU_ID_OFFS			16+#define CFCR_MRVL_CPU_ID_MASK			(0x1 << CFCR_MRVL_CPU_ID_OFFS)+#define CFCR_ARM_CPU_ID				(0x0 << CFCR_MRVL_CPU_ID_OFFS)+#define CFCR_MRVL_CPU_ID			(0x1 << CFCR_MRVL_CPU_ID_OFFS)+#define CFCR_VFP_SUB_ARC_NUM_OFFS		7+#define CFCR_VFP_SUB_ARC_NUM_MASK		(0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)+#define CFCR_VFP_SUB_ARC_NUM_1			(0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)+#define CFCR_VFP_SUB_ARC_NUM_2			(0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)++/* CPU_L2_CONFIG_REG fields */+#ifdef MV_CPU_LE+#define CL2CR_L2_ECC_EN_OFFS			2+#define CL2CR_L2_WT_MODE_OFFS			4+#else+#define CL2CR_L2_ECC_EN_OFFS			26+#define CL2CR_L2_WT_MODE_OFFS			28+#endif++#define CL2CR_L2_ECC_EN_MASK			(1 << CL2CR_L2_ECC_EN_OFFS)+#define CL2CR_L2_WT_MODE_MASK			(1 << CL2CR_L2_WT_MODE_OFFS)++/*******************************************/+/* Main Interrupt Controller Registers Map */+/*******************************************/++#define CPU_MAIN_INT_CAUSE_REG			0x20200+#define CPU_MAIN_IRQ_MASK_REG			0x20204+#define CPU_MAIN_FIQ_MASK_REG			0x20208+#define CPU_ENPOINT_MASK_REG			0x2020C+#define CPU_MAIN_INT_CAUSE_HIGH_REG		0x20210+#define CPU_MAIN_IRQ_MASK_HIGH_REG		0x20214+#define CPU_MAIN_FIQ_MASK_HIGH_REG		0x20218+#define CPU_ENPOINT_MASK_HIGH_REG		0x2021C+++/*******************************************/+/* ARM Doorbell Registers Map		   */+/*******************************************/++#define CPU_HOST_TO_ARM_DRBL_REG		0x20400+#define CPU_HOST_TO_ARM_MASK_REG		0x20404+#define CPU_ARM_TO_HOST_DRBL_REG		0x20408+#define CPU_ARM_TO_HOST_MASK_REG		0x2040C++++/* CPU control register map */+/* Set bits means value is about to change according to new value */+#define CPU_CONFIG_DEFAULT_MASK         	(CCR_VEC_INIT_LOC_MASK  | CCR_AHB_ERROR_PROP_MASK)      ++#define CPU_CONFIG_DEFAULT                      (CCR_VEC_INIT_LOC_FF00)+                 +/* CPU Control and status defaults */+#define CPU_CTRL_STAT_DEFAULT_MASK              (CCSR_PCI_ACCESS_MASK)+                                                                        ++#define CPU_CTRL_STAT_DEFAULT                   (CCSR_PCI_ACCESS_ENABLE)++#endif /* __INCmvCpuIfRegsh */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c	2010-11-09 20:28:08.042495347 +0100@@ -0,0 +1,324 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#include "mvSysAudio.h"++/*******************************************************************************+* mvAudioWinSet - Set AUDIO target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) +*       address window, also known as address decode window. +*       After setting this target window, the AUDIO will be able to access the +*       target within the address window. +*+* INPUT:+*       winNum      - AUDIO target address decode window number.+*       pAddrDecWin - AUDIO target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if address window overlapps with other address decode windows.+*       MV_BAD_PARAM if base address is invalid parameter or target is +*       unknown.+*+*******************************************************************************/+MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)+{+    MV_TARGET_ATTRIB    targetAttribs;+    MV_DEC_REGS         decRegs;++    /* Parameter checking   */+    if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);+        return MV_BAD_PARAM;+    }+    +    /* check if address is aligned to the size */+    if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+    {+		mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\+			   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+			   winNum,+			   mvCtrlTargetNameGet(pAddrDecWin->target), +			   pAddrDecWin->addrWin.baseLow,+			   pAddrDecWin->addrWin.size);+		return MV_ERROR;+    }++    decRegs.baseReg = 0;+    decRegs.sizeReg = 0;++    if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+    {+        mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);+        return MV_ERROR;+    }++    mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);+                                                                                                                         +    /* set attributes */+    decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;+    decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);++    /* set target ID */+    decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;+    decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);++    if (pAddrDecWin->enable == MV_TRUE)+    {+        decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;+    }+    else+    {+        decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;+    }++    MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);+    MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);+    +    return MV_OK;+}++/*******************************************************************************+* mvAudioWinGet - Get AUDIO peripheral target address window.+*+* DESCRIPTION:+*       Get AUDIO peripheral target address window.+*+* INPUT:+*       winNum - AUDIO target address decode window number.+*+* OUTPUT:+*       pAddrDecWin - AUDIO target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)+{+    MV_DEC_REGS         decRegs;+    MV_TARGET_ATTRIB    targetAttrib;+                                                                                                                         +    /* Parameter checking   */+    if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s : ERR. Invalid winNum %d\n", +                    __FUNCTION__,  winNum);+        return MV_NOT_SUPPORTED;+    }++    decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );+    decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );+ +    if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )+    {+        mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);+        return MV_ERROR; +    }+       +    /* attrib and targetId */+    targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >> +		MV_AUDIO_WIN_ATTR_OFFSET;+    targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >> +		MV_AUDIO_WIN_TARGET_OFFSET;+ +    pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++    /* Check if window is enabled   */+    if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK) +    {+        pAddrDecWin->enable = MV_TRUE;+    }+    else+    {+        pAddrDecWin->enable = MV_FALSE;+    }+    return MV_OK;+}+/*******************************************************************************+* mvAudioAddrDecShow - Print the AUDIO address decode map.+*+* DESCRIPTION:+*		This function print the AUDIO address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvAudioAddrDecShow(MV_VOID)+{++	MV_AUDIO_DEC_WIN win;+	int i;++	if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0)) +		return;+++	mvOsOutput( "\n" );+	mvOsOutput( "AUDIO:\n" );+	mvOsOutput( "----\n" );++	for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )+	{+            memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );++	    mvOsOutput( "win%d - ", i );++	    if( mvAudioWinGet( i, &win ) == MV_OK )+	    {+	        if( win.enable )+	        {+                    mvOsOutput( "%s base %08x, ",+                    mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );+                    mvOsOutput( "...." );++                    mvSizePrint( win.addrWin.size );+    +		    mvOsOutput( "\n" );+                }+		else+		mvOsOutput( "disable\n" );+	    }+	}+}+++/*******************************************************************************+* mvAudioWinInit - Initialize the integrated AUDIO target address window.+*+* DESCRIPTION:+*       Initialize the AUDIO peripheral target address window.+*+* INPUT:+*+*+* OUTPUT:+*     +*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvAudioInit(MV_VOID)+{+    int             winNum;+    MV_AUDIO_DEC_WIN  audioWin;+    MV_CPU_DEC_WIN  cpuAddrDecWin;+    MV_U32          status;++    mvAudioHalInit();++    /* Initiate Audio address decode */++    /* First disable all address decode windows */+    for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)+    {+        MV_U32  regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));+        regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;+        MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);+    }++    for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)+    {++		/* We will set the Window to DRAM_CS0 in default */+		/* first get attributes from CPU If */+		status = mvCpuIfTargetWinGet(SDRAM_CS0,+									 &cpuAddrDecWin);+	+		if (MV_OK != status)+		{+				mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);+			return MV_ERROR;+		}+	+		if (cpuAddrDecWin.enable == MV_TRUE)+		{+			audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+			audioWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow;+			audioWin.addrWin.size     = cpuAddrDecWin.addrWin.size;+			audioWin.enable           = MV_TRUE;+			audioWin.target           = SDRAM_CS0;+	+			if(MV_OK != mvAudioWinSet(winNum, &audioWin))+			{+				return MV_ERROR;+			}+		}+	}++    return MV_OK;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h	2010-11-09 20:28:08.082495466 +0100@@ -0,0 +1,123 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#ifndef __INCMVSysAudioH+#define __INCMVSysAudioH++#include "mvCommon.h"+#include "audio/mvAudio.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "ctrlEnv/sys/mvCpuIf.h"++/***********************************/+/* Audio Address Decoding registers*/+/***********************************/++#define MV_AUDIO_MAX_ADDR_DECODE_WIN 		2+#define MV_AUDIO_RECORD_WIN_NUM			0+#define MV_AUDIO_PLAYBACK_WIN_NUM		1++#define MV_AUDIO_WIN_CTRL_REG(win)        (AUDIO_REG_BASE + 0xA04 + ((win)<<3))+#define MV_AUDIO_WIN_BASE_REG(win)        (AUDIO_REG_BASE + 0xA00 + ((win)<<3))++#define MV_AUDIO_RECORD_WIN_CTRL_REG		MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)+#define MV_AUDIO_RECORD_WIN_BASE_REG		MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)+#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG		MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)+#define MV_AUDIO_PLAYBACK_WIN_BASE_REG		MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)+++/* BITs in Windows 0-3 Control and Base Registers */+#define MV_AUDIO_WIN_ENABLE_BIT               0+#define MV_AUDIO_WIN_ENABLE_MASK              (1<<MV_AUDIO_WIN_ENABLE_BIT)++#define MV_AUDIO_WIN_TARGET_OFFSET            4+#define MV_AUDIO_WIN_TARGET_MASK              (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)++#define MV_AUDIO_WIN_ATTR_OFFSET              8+#define MV_AUDIO_WIN_ATTR_MASK                (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)++#define MV_AUDIO_WIN_SIZE_OFFSET              16+#define MV_AUDIO_WIN_SIZE_MASK                (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)++#define MV_AUDIO_WIN_BASE_OFFSET              16+#define MV_AUDIO_WIN_BASE_MASK                (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)+++typedef struct _mvAudioDecWin+{+    MV_TARGET     target;+    MV_ADDR_WIN   addrWin;    /* An address window*/+    MV_BOOL       enable;     /* Address decode window is enabled/disabled    */+ +} MV_AUDIO_DEC_WIN;+++MV_STATUS mvAudioInit(MV_VOID);+MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);+MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);+MV_STATUS mvAudioWinInit(MV_VOID);+MV_VOID   mvAudioAddrDecShow(MV_VOID);+++#endif+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c	2010-11-09 20:28:08.121241788 +0100@@ -0,0 +1,382 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvSysCesa.h"++#if (MV_CESA_VERSION >= 2)+MV_TARGET tdmaAddrDecPrioTable[] =+{+#if defined(MV_INCLUDE_SDRAM_CS0)+    SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+    SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+    SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+    SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_PEX)+    PEX0_MEM,+#endif++    TBL_TERM+};++/*******************************************************************************+* mvCesaWinGet - Get TDMA target address window.+*+* DESCRIPTION:+*       Get TDMA target address window.+*+* INPUT:+*       winNum - TDMA target address decode window number.+*+* OUTPUT:+*       pDecWin - TDMA target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)+{                                                                                                                         +    MV_DEC_WIN_PARAMS   winParam;+    MV_U32              sizeReg, baseReg;++    /* Parameter checking   */+    if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)+    {+        mvOsPrintf("%s : ERR. Invalid winNum %d\n", +                    __FUNCTION__, winNum);+        return MV_NOT_SUPPORTED;+    }++    baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );+    sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );+ +   /* Check if window is enabled   */+    if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK) +    {+        pDecWin->enable = MV_TRUE;++        /* Extract window parameters from registers */+        winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET; +        winParam.attrib   = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;+        winParam.size     = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;+        winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);++        /* Translate the decode window parameters to address decode struct */+        if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))+        {+            mvOsPrintf("Failed to translate register parameters to CESA address" \+                       " decode window structure\n");+            return MV_ERROR;        +        }+    }+    else+    {+        pDecWin->enable = MV_FALSE;+    }+    return MV_OK;+}++/*******************************************************************************+* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviur is expected in case TDMA address decode +*       windows overlapps.+*       This function detects TDMA address decode windows overlapping of a +*       specified window. The function does not check the window itself for +*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE     - if the given address window overlap current address+*                   decode map, +*       MV_FALSE    - otherwise, MV_ERROR if reading invalid data +*                   from registers.+*+*******************************************************************************/+static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)+{+    MV_U32          winNumIndex;+    MV_DEC_WIN      addrDecWin;+    +    for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)+    {+        /* Do not check window itself       */+        if (winNumIndex == winNum)+        {+            continue;+        }++        /* Get window parameters    */+        if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))+        {+            mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);+            return MV_ERROR;+        }++        /* Do not check disabled windows    */+        if(addrDecWin.enable == MV_FALSE)+        {+            continue;+        }++        if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+        {+            return MV_TRUE;+        }        +    }+    return MV_FALSE;+}++/*******************************************************************************+* mvCesaTdmaWinSet - Set CESA TDMA target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) +*       address window, also known as address decode window. +*       After setting this target window, the CESA TDMA will be able to access the +*       target within the address window. +*+* INPUT:+*       winNum      - CESA TDMA target address decode window number.+*       pAddrDecWin - CESA TDMA target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR        - if address window overlapps with other address decode windows.+*       MV_BAD_PARAM    - if base address is invalid parameter or target is +*                       unknown.+*+*******************************************************************************/+static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)+{+    MV_DEC_WIN_PARAMS   winParams;+    MV_U32              sizeReg, baseReg;+    +    /* Parameter checking   */+    if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)+    {+        mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);+        return MV_BAD_PARAM;+    }++    /* Check if the requested window overlapps with current windows     */+    if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))+    {+        mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);+        return MV_ERROR;+    }++    /* check if address is aligned to the size */+    if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))+    {+        mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\+                   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+                   winNum,+                   mvCtrlTargetNameGet(pDecWin->target), +                   pDecWin->addrWin.baseLow,+                   pDecWin->addrWin.size);+        return MV_ERROR;+    }++    if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))+    {+        mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);+        return MV_ERROR;+    }++    /* set Size, Attributes and TargetID */+    sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |+               ((winParams.attrib   << MV_CESA_TDMA_WIN_ATTR_OFFSET)   & MV_CESA_TDMA_WIN_ATTR_MASK)   |+               ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));++    if (pDecWin->enable == MV_TRUE)+    {+        sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;+    }+    else+    {+        sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;+    }++    /* Update Base value  */+    baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);     ++    MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);+    MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);+        +    return MV_OK;+}+++static MV_STATUS   mvCesaTdmaAddrDecInit (void)+{+    MV_U32          winNum;+    MV_STATUS       status;+    MV_CPU_DEC_WIN  cpuAddrDecWin;+    MV_DEC_WIN      cesaWin;+    MV_U32          winPrioIndex = 0;++    /* First disable all address decode windows */+    for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)+    {+        MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);+    }++    /* Go through all windows in user table until table terminator      */+    winNum = 0;+    while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) && +           (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) )    {++        /* first get attributes from CPU If */+        status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex], +                                     &cpuAddrDecWin);+        if(MV_NO_SUCH == status){+	    winPrioIndex++;+            continue;+	}++        if (MV_OK != status)+        {+            mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",+                        winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);+            return MV_ERROR;+        }+        if (cpuAddrDecWin.enable == MV_TRUE)+        {+            cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+            cesaWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow;+            cesaWin.addrWin.size     = cpuAddrDecWin.addrWin.size;+            cesaWin.enable           = MV_TRUE;+            cesaWin.target           = tdmaAddrDecPrioTable[winPrioIndex];++#if defined(MV646xx) +            /* Get the default attributes for that target window */+            mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);+#endif /* MV646xx */ ++            if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))+            {+                mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",+                           winNum);+                return MV_ERROR;+            }+            winNum++;+        }+        winPrioIndex++;+    }+    return MV_OK;+}+#endif /* MV_CESA_VERSION >= 2 */+++++MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)+{+    MV_U32 cesaCryptEngBase;+    MV_CPU_DEC_WIN addrDecWin;++    if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)+    {+        mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",+                sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);+        return MV_FAIL;+    }+#if 0+    if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)+        cesaCryptEngBase = addrDecWin.addrWin.baseLow;+    else+    {+        mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");+        return MV_ERROR;+    }+#else+        cesaCryptEngBase = (MV_U32)pSramBase;+#endif     ++#if 0 /* Already done in the platform init */+#if (MV_CESA_VERSION >= 2)+    mvCesaTdmaAddrDecInit();+#endif /* MV_CESA_VERSION >= 2 */+#endif+	return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase, +			     osHandle);++}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h	2010-11-09 20:28:08.152495441 +0100@@ -0,0 +1,100 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __mvSysCesa_h__+#define __mvSysCesa_h__+++#include "mvCommon.h"+#include "cesa/mvCesa.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "ctrlEnv/sys/mvCpuIf.h"++/***************************** TDMA Registers *************************************/++#define MV_CESA_TDMA_ADDR_DEC_WIN           4++#define MV_CESA_TDMA_BASE_ADDR_REG(win)     (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))++#define MV_CESA_TDMA_WIN_CTRL_REG(win)      (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))++#define MV_CESA_TDMA_WIN_ENABLE_BIT         0+#define MV_CESA_TDMA_WIN_ENABLE_MASK        (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)++#define MV_CESA_TDMA_WIN_TARGET_OFFSET      4 +#define MV_CESA_TDMA_WIN_TARGET_MASK        (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)++#define MV_CESA_TDMA_WIN_ATTR_OFFSET        8 +#define MV_CESA_TDMA_WIN_ATTR_MASK          (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)++#define MV_CESA_TDMA_WIN_SIZE_OFFSET        16+#define MV_CESA_TDMA_WIN_SIZE_MASK          (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)++#define MV_CESA_TDMA_WIN_BASE_OFFSET        16+#define MV_CESA_TDMA_WIN_BASE_MASK          (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)+++MV_STATUS   mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c	2010-11-09 20:28:08.192500699 +0100@@ -0,0 +1,348 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++/* includes */++#include "ddr2/mvDramIf.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "ctrlEnv/sys/mvSysDram.h"++/* #define MV_DEBUG */+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);++/*******************************************************************************+* mvDramIfWinSet - Set DRAM interface address decode window+*+* DESCRIPTION: +*       This function sets DRAM interface address decode window.+*+* INPUT:+*	    target      - System target. Use only SDRAM targets.+*       pAddrDecWin - SDRAM address window structure.+*+* OUTPUT:+*       None+*+* RETURN:+*       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK+*       otherwise.+*******************************************************************************/+MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)+{+	MV_U32 baseReg=0,sizeReg=0;+	MV_U32 baseToReg=0 , sizeToReg=0;++    /* Check parameters */+	if (!MV_TARGET_IS_DRAM(target))+	{+		mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);+		return MV_BAD_PARAM;+	}++    /* Check if the requested window overlaps with current enabled windows	*/+    if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))+	{+        mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);+		return MV_BAD_PARAM;+	}++	/* check if address is aligned to the size */+	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+	{+		mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\+				   "\nAddress 0x%08x is unaligned to size 0x%x.\n",+                   target, +				   pAddrDecWin->addrWin.baseLow,+				   pAddrDecWin->addrWin.size);+		return MV_ERROR;+	}++	/* read base register*/+	baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));++	/* read size register */+	sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));++	/* BaseLow[31:16] => base register [31:16]		*/+	baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;++	/* Write to address decode Base Address Register                  */+	baseReg &= ~SCBAR_BASE_MASK;+	baseReg |= baseToReg;++	/* Translate the given window size to register format			*/+	sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);++	/* Size parameter validity check.                                   */+	if (-1 == sizeToReg)+	{+		mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);+		return MV_BAD_PARAM;+	}++	/* set size */+	sizeReg &= ~SCSR_SIZE_MASK;+	/* Size is located at upper 16 bits */+	sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);++	/* enable/Disable */+	if (MV_TRUE == pAddrDecWin->enable)+	{+		sizeReg |= SCSR_WIN_EN;+	}+	else+	{+		sizeReg &= ~SCSR_WIN_EN;+	}++	/* 3) Write to address decode Base Address Register                   */+	MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);++	/* Write to address decode Size Register                        	*/+	MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);+	+	return MV_OK;+}+/*******************************************************************************+* mvDramIfWinGet - Get DRAM interface address decode window+*+* DESCRIPTION: +*       This function gets DRAM interface address decode window.+*+* INPUT:+*	    target - System target. Use only SDRAM targets.+*+* OUTPUT:+*       pAddrDecWin - SDRAM address window structure.+*+* RETURN:+*       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK+*       otherwise.+*******************************************************************************/+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)+{+	MV_U32 baseReg,sizeReg;+	MV_U32 sizeRegVal;+	/* Check parameters */+	if (!MV_TARGET_IS_DRAM(target))+	{+		mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);+		return MV_ERROR;+	}++	/* Read base and size registers */+	sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));+	baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));++	sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;++	pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,+							SCSR_SIZE_ALIGNMENT);++    	/* Check if ctrlRegToSize returned OK */+	if (-1 == pAddrDecWin->addrWin.size)+	{+		mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);+		return MV_ERROR;+	}++	/* Extract base address						*/+	/* Base register [31:16] ==> baseLow[31:16] 		*/+	pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;++	pAddrDecWin->addrWin.baseHigh =  0;+++	if (sizeReg & SCSR_WIN_EN)+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else+	{+		pAddrDecWin->enable = MV_FALSE;			+	}++	return MV_OK;+}+/*******************************************************************************+* mvDramIfWinEnable - Enable/Disable SDRAM address decode window+*+* DESCRIPTION: +*		This function enable/Disable SDRAM address decode window.+*+* INPUT:+*	    target - System target. Use only SDRAM targets.+*+* OUTPUT:+*		None.+*+* RETURN:+*		MV_ERROR in case function parameter are invalid, MV_OK otherewise.+*+*******************************************************************************/+MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)+{+	MV_DRAM_DEC_WIN 	addrDecWin;++	/* Check parameters */+	if (!MV_TARGET_IS_DRAM(target))+	{+		mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);+		return MV_ERROR;+	}++	if (enable == MV_TRUE) +	{   /* First check for overlap with other enabled windows				*/+		if (MV_OK != mvDramIfWinGet(target, &addrDecWin))+		{+			mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n", +                                                                        target);+			return MV_ERROR;+		}+		/* Check for overlapping */+		if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))+		{+			/* No Overlap. Enable address decode winNum window              */+			MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);+		}+		else+		{   /* Overlap detected	*/+			mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",+                                                                        target);+			return MV_ERROR;+		}+	}+	else+	{   /* Disable address decode winNum window                             */+		MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);+	}++	return MV_OK;+}++/*******************************************************************************+* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window+*+* DESCRIPTION:+*		This function scan each SDRAM address decode window to test if it +*		overlapps the given address windoow +*+* INPUT:+*       target      - SDRAM target where the function skips checking.+*       pAddrDecWin - The tested address window for overlapping with +*					  SDRAM windows.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlaps any enabled address+*       decode map, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)+{+	MV_TARGET	targetNum;+	MV_DRAM_DEC_WIN 	addrDecWin;+	+	for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)+	{+		/* don't check our winNum or illegal targets */+		if (targetNum == target)+		{+			continue;+		}+		+		/* Get window parameters 	*/+		if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))+		{+			mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");+			return MV_ERROR;+		}+	+		/* Do not check disabled windows	*/+		if (MV_FALSE == addrDecWin.enable)+		{+			continue;+		}+	+		if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))+		{                    +			mvOsPrintf(+			"sdramIfWinOverlap: Required target %d overlap winNum %d\n", +			target, targetNum);+			return MV_TRUE;           +		}+	}+	+	return MV_FALSE;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h	2010-11-09 20:28:08.232495451 +0100@@ -0,0 +1,80 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __sysDram+#define __sysDram++/* This structure describes CPU interface address decode window               */+typedef struct _mvDramIfDecWin +{+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */+}MV_DRAM_DEC_WIN;++MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);+MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c	2010-11-09 20:28:08.262495451 +0100@@ -0,0 +1,658 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#include "ctrlEnv/sys/mvSysGbe.h"++++typedef struct _mvEthDecWin+{+    MV_TARGET     target;+    MV_ADDR_WIN   addrWin;  /* An address window*/+    MV_BOOL       enable;   /* Address decode window is enabled/disabled */+  +}MV_ETH_DEC_WIN;++MV_TARGET ethAddrDecPrioTap[] =+{+#if defined(MV_INCLUDE_SDRAM_CS0)+        SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+        SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+        SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+        SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_DEVICE_CS0)+        DEVICE_CS0,+#endif+#if defined(MV_INCLUDE_DEVICE_CS1)+        DEVICE_CS1,+#endif+#if defined(MV_INCLUDE_DEVICE_CS2)+        DEVICE_CS2,+#endif+#if defined(MV_INCLUDE_DEVICE_CS3)+        DEVICE_CS3,+#endif+#if defined(MV_INCLUDE_PEX)+        PEX0_IO,+#endif+        TBL_TERM+};++static MV_STATUS   ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);+static MV_STATUS   mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);+static MV_STATUS   mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);++                                                                                                                             +/*******************************************************************************+* mvEthWinInit - Initialize ETH address decode windows +*+* DESCRIPTION:+*               This function initialize ETH window decode unit. It set the +*               default address decode windows of the unit.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if setting fail.+*******************************************************************************/+/* Configure EthDrv memory map registes. */+MV_STATUS 	mvEthWinInit (int port)+{+    MV_U32          winNum, status, winPrioIndex=0, i, regVal=0;+    MV_ETH_DEC_WIN  ethWin;+    MV_CPU_DEC_WIN  cpuAddrDecWin;+    static MV_U32   accessProtReg = 0;++#if (MV_ETH_VERSION <= 1)+    static MV_BOOL  isFirst = MV_TRUE;++    if(isFirst == MV_FALSE)+    {+        MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);+        return MV_OK;+    }+    isFirst = MV_FALSE;+#endif /* MV_GIGA_ETH_VERSION */++    /* Initiate Ethernet address decode */++    /* First disable all address decode windows */+    for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)+    {+        regVal |= MV_BIT_MASK(winNum);+    }+    MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);++   /* Go through all windows in user table until table terminator      */+    for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) && +                    (winNum < ETH_MAX_DECODE_WIN)); )+    {+        /* first get attributes from CPU If */+        status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex], +                                     &cpuAddrDecWin);++        if(MV_NO_SUCH == status)+        {+            winPrioIndex++;+            continue;+        }+		if (MV_OK != status)+		{+			mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");+			return MV_ERROR;+		}++        if (cpuAddrDecWin.enable == MV_TRUE)+        {+            ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+            ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;+            ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;+            ethWin.enable = MV_TRUE;+            ethWin.target = ethAddrDecPrioTap[winPrioIndex];++            if(MV_OK != mvEthWinSet(port, winNum, ðWin))+            {+                mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",+                           winNum);+                return MV_ERROR;+            }+            winNum++;+        }+        winPrioIndex ++;+    }++    /* set full access to all windows. */+    for(i=0; i<winNum; i++)+    {+        accessProtReg |= (FULL_ACCESS << (i*2));+    }+    MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);++    return MV_OK;+}++/*******************************************************************************+* mvEthWinSet - Set ETH target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)+*       address window, also known as address decode window.+*       After setting this target window, the ETH will be able to access the+*       target within the address window.+*+* INPUT:+*       winNum      - ETH to target address decode window number.+*       pAddrDecWin - ETH target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if address window overlapps with other address decode windows.+*       MV_BAD_PARAM if base address is invalid parameter or target is+*       unknown.+*+*******************************************************************************/+MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)+{+    MV_TARGET_ATTRIB    targetAttribs;+    MV_DEC_REGS         decRegs;+    +    /* Parameter checking   */+    if (winNum >= ETH_MAX_DECODE_WIN)+    {+        mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);+        return MV_BAD_PARAM;+    }    +    +    /* Check if the requested window overlapps with current windows     */+    if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))+    {+        mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);+        return MV_ERROR;+    }++	/* check if address is aligned to the size */+	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+	{+		mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\+				   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+				   winNum,+				   mvCtrlTargetNameGet(pAddrDecWin->target), +				   pAddrDecWin->addrWin.baseLow,+				   pAddrDecWin->addrWin.size);+		return MV_ERROR;+	}++    +    decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));+    decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));+    +    if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+    {+        mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");+        return MV_ERROR;+    }+    +    mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);+    +    /* set attributes */+    decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;+    decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;+    /* set target ID */+    decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;+    decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;+    +    /* for the safe side we disable the window before writing the new+    values */+    mvEthWinEnable(port, winNum, MV_FALSE);+    MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);+    +    /* Write to address decode Size Register                            */+    MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);+    +    /* Enable address decode target window                              */+    if (pAddrDecWin->enable == MV_TRUE)+    {+            mvEthWinEnable(port, winNum, MV_TRUE);+    }+    +    return MV_OK;+}++/*******************************************************************************+* mvETHWinGet - Get dma peripheral target address window.+*+* DESCRIPTION:+*               Get ETH peripheral target address window.+*+* INPUT:+*       winNum - ETH to target address decode window number.+*+* OUTPUT:+*       pAddrDecWin - ETH target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)+{+    MV_DEC_REGS decRegs;+    MV_TARGET_ATTRIB targetAttrib;+    +    /* Parameter checking   */+    if (winNum >= ETH_MAX_DECODE_WIN)+    {+        mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);+        return MV_NOT_SUPPORTED;+    }+    +    decRegs.baseReg =  MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));+    decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));+    +    if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))+    {+        mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");+        return MV_ERROR;+    }+    +    /* attrib and targetId */+    targetAttrib.attrib = +     (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;+    targetAttrib.targetId = +     (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;+    +    pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);+    +    /* Check if window is enabled   */+    if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )+    {+        pAddrDecWin->enable = MV_TRUE;+    }+    else+    {+        pAddrDecWin->enable = MV_FALSE;+    }+    +        return MV_OK;+}++/*******************************************************************************+* mvEthWinEnable - Enable/disable a ETH to target address window+*+* DESCRIPTION:+*       This function enable/disable a ETH to target address window.+*       According to parameter 'enable' the routine will enable the+*       window, thus enabling ETH accesses (before enabling the window it is+*       tested for overlapping). Otherwise, the window will be disabled.+*+* INPUT:+*       winNum - ETH to target address decode window number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if decode window number was wrong or enabled window overlapps.+*+*******************************************************************************/+MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)+{+    MV_ETH_DEC_WIN addrDecWin;++    /* Parameter checking   */+    if (winNum >= ETH_MAX_DECODE_WIN)+    {+        mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);+        return MV_ERROR;+    }++    if (enable == MV_TRUE)+    {   /* First check for overlap with other enabled windows               */+        /* Get current window */+        if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))+        {+            mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");+            return MV_ERROR;+        }+        /* Check for overlapping */+        if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))+        {+            /* No Overlap. Enable address decode target window              */+            MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));+        }+        else+        {   /* Overlap detected */+            mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");+            return MV_ERROR;+        }+    }+    else+    {   /* Disable address decode target window                             */+        MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));+    }+    return MV_OK;+}+ +/*******************************************************************************+* mvEthWinTargetGet - Get Window number associated with target+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*       window number+*+*******************************************************************************/+MV_U32  mvEthWinTargetGet(int port, MV_TARGET target)+{+    MV_ETH_DEC_WIN decWin;+    MV_U32 winNum;++    /* Check parameters */+    if (target >= MAX_TARGETS)+    {+        mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);+        return 0xffffffff;+    }++    for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)+    {+        if (mvEthWinGet(port, winNum,&decWin) != MV_OK)+        {+            mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");+            return 0xffffffff;+        }++        if (decWin.enable == MV_TRUE)+        {+            if (decWin.target == target)+            {+                return winNum;+            }  +        }+    }+    return 0xFFFFFFFF;+}+ +/*******************************************************************************+* mvEthProtWinSet - Set access protection of Ethernet to target window.+*+* DESCRIPTION:+*       Each Ethernet port can be configured with access attributes for each +*       of the Ethenret to target windows (address decode windows). This+*       function sets access attributes to a given window for the given channel.+*+* INPUTS:+*       ethPort   - ETH channel number. See MV_ETH_CHANNEL enumerator.+*       winNum - IETH to target address decode window number.+*       access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR in case window number is invalid or access right reserved.+*+*******************************************************************************/+MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)+{    +    MV_U32 protReg;++    /* Parameter checking   */+    if(portNo >= mvCtrlEthMaxPortGet())+    {+        mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);+        return MV_ERROR;+    }+    +    if (winNum >= ETH_MAX_DECODE_WIN)+    {+            mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);+            return MV_ERROR;+    }++    if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))+    {+        mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);+        return MV_ERROR;+    }+    /* Read current protection register */+    protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));+                          +    /* Clear protection window field */+    protReg &= ~(ETH_PROT_WIN_MASK(winNum));++    /* Set new protection field value */+    protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));+    +    /* Write protection register back   */+    MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);++    return MV_OK;+}               ++/*******************************************************************************+* ethWinOverlapDetect - Detect ETH address windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviur is expected in case ETH address decode+*       windows overlapps.+*       This function detects ETH address decode windows overlapping of a+*       specified window. The function does not check the window itself for+*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data+*       from registers.+*+*******************************************************************************/+static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)+{+    MV_U32              baseAddrEnableReg;+    MV_U32              winNumIndex;+    MV_ETH_DEC_WIN      addrDecWin;+                                                                                                                             +    /* Read base address enable register. Do not check disabled windows     */+    baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));+                                                                                                                             +    for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)+    {+        /* Do not check window itself           */+        if (winNumIndex == winNum)+        {+            continue;+        }+    +        /* Do not check disabled windows        */+        if (baseAddrEnableReg & (1 << winNumIndex))+        {+            continue;+        }+    +        /* Get window parameters        */+        if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))+        {+            mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");+            return MV_ERROR;+        }+/*    +        mvOsPrintf("ethWinOverlapDetect:\n+            winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",+            winNumIndex,+            addrDecWin.addrWin.baseHigh,+            addrDecWin.addrWin.baseLow,+            addrDecWin.addrWin.size,+            addrDecWin.enable);+*/+        if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+        {+            return MV_TRUE;+        }+    }+    return MV_FALSE;+}++/*******************************************************************************+* mvEthAddrDecShow - Print the Etherent address decode map.+*+* DESCRIPTION:+*       This function print the Etherent address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+void    mvEthPortAddrDecShow(int port)+{+    MV_ETH_DEC_WIN  win;+    int             i;++    mvOsOutput( "\n" );+    mvOsOutput( "ETH %d:\n", port );+    mvOsOutput( "----\n" );++    for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )+    {+        memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );++        mvOsOutput( "win%d - ", i );++        if( mvEthWinGet(port, i, &win ) == MV_OK )+        {+            if( win.enable )+            {+                mvOsOutput( "%s base %08x, ",+                mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );+                mvOsOutput( "...." );+                mvSizePrint( win.addrWin.size );++                mvOsOutput( "\n" );+            }+            else+                mvOsOutput( "disable\n" );+        }+    }+    return;+}++void    mvEthAddrDecShow(void)+{+    int port;++    for(port=0; port<mvCtrlEthMaxPortGet(); port++)+    {+	if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;+    +        mvEthPortAddrDecShow(port);+    }+}+++void    mvEthInit(void)+{+    MV_U32 port;++    /* Power down all existing ports */+    for(port=0; port<mvCtrlEthMaxPortGet(); port++)+    {+	    if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) +            continue;++        mvEthPortPowerUp(port);+	    mvEthWinInit(port);+    }+    mvEthHalInit();+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h	2010-11-09 20:28:08.292495558 +0100@@ -0,0 +1,113 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSysGbeh+#define __INCmvSysGbeh++#include "mvCommon.h"+#include "eth/mvEth.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "ctrlEnv/sys/mvCpuIf.h"++#define ETH_WIN_BASE_REG(port, win)         (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))+#define ETH_WIN_SIZE_REG(port, win)         (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))+#define ETH_WIN_REMAP_REG(port, win)        (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))+#define ETH_BASE_ADDR_ENABLE_REG(port)      (MV_ETH_REG_BASE(port) + 0x290)+#define ETH_ACCESS_PROTECT_REG(port)        (MV_ETH_REG_BASE(port) + 0x294)++/**** Address decode parameters ****/++/* Ethernet Base Address Register bits */+#define ETH_MAX_DECODE_WIN              6+#define ETH_MAX_HIGH_ADDR_REMAP_WIN     4++/* Ethernet Port Access Protect (EPAP) register */++/* The target associated with this window*/+#define ETH_WIN_TARGET_OFFS             0 +#define ETH_WIN_TARGET_MASK             (0xf << ETH_WIN_TARGET_OFFS)+/* The target attributes Associated with window */+#define ETH_WIN_ATTR_OFFS               8 +#define ETH_WIN_ATTR_MASK               (0xff << ETH_WIN_ATTR_OFFS)++/* Ethernet Port Access Protect Register (EPAPR) */+#define ETH_PROT_NO_ACCESS              NO_ACCESS_ALLOWED+#define ETH_PROT_READ_ONLY              READ_ONLY+#define ETH_PROT_FULL_ACCESS            FULL_ACCESS+#define ETH_PROT_WIN_OFFS(winNum)       (2 * (winNum))+#define ETH_PROT_WIN_MASK(winNum)       (0x3 << ETH_PROT_WIN_OFFS(winNum))++MV_STATUS   mvEthWinInit (int port);+MV_STATUS   mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);+MV_U32      mvEthWinTargetGet(int port, MV_TARGET target);+MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS+		access);++void        mvEthPortAddrDecShow(int port);++MV_VOID     mvEthAddrDecShow(MV_VOID);++void        mvEthInit(void);++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c	2010-11-09 20:28:08.332495446 +0100@@ -0,0 +1,1697 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "ctrlEnv/sys/mvSysPex.h"++/* this structure describes the mapping between a Pex Window and a CPU target*/+typedef struct _pexWinToTarget+{+	MV_TARGET target;+	MV_BOOL	  enable;++}PEX_WIN_TO_TARGET;++/* this array is a priority array that define How Pex windows should be +configured , We have only 6 Pex Windows that can be configured , but we+have maximum of 9 CPU target windows ! the following array is a priority+array where the lowest index has the highest priotiy and the highest +index has the lowest priority of being cnfigured */++MV_U32	pexDevBarPrioTable[] =+{+#if defined(MV_INCLUDE_DEVICE_CS0)+    DEVICE_CS0,+#endif+#if defined(MV_INCLUDE_DEVICE_CS1)+    DEVICE_CS1,+#endif+#if defined(MV_INCLUDE_DEVICE_CS2)+    DEVICE_CS2,+#endif                                               +#if defined(MV_INCLUDE_DEVICE_CS3)+    DEVICE_CS3,+#endif+/*+#if defined(MV_INCLUDE_DEVICE_CS4)+    DEVICE_CS4,+#endif+*/+    TBL_TERM+};+++/* PEX Wins registers offsets are inconsecutive. This struct describes WIN	*/+/* register offsets	and its function where its is located.					*/+/* Also, PEX address remap registers offsets are inconsecutive. This struct	*/+/* describes address remap register offsets									*/+typedef struct _pexWinRegInfo+{+    MV_U32 baseLowRegOffs;+	MV_U32 baseHighRegOffs;+	MV_U32 sizeRegOffs;+	MV_U32 remapLowRegOffs;+	MV_U32 remapHighRegOffs;++}PEX_WIN_REG_INFO;++static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,+									 MV_ADDR_WIN *pAddrWin);+static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,+								  PEX_WIN_REG_INFO *pWinRegInfo);++static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);++static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);+static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,+								   MV_ADDR_WIN *pAddrWin);+const MV_8* pexBarNameGet( MV_U32 bar );+++/*******************************************************************************+* mvPexInit - Initialize PEX interfaces+*+* DESCRIPTION:+*+* This function is responsible of intialization of the Pex Interface , It +* configure the Pex Bars and Windows in the following manner:+*+*  Assumptions : +*				Bar0 is always internal registers bar+*			    Bar1 is always the DRAM bar+*				Bar2 is always the Device bar+*+*  1) Sets the Internal registers bar base by obtaining the base from+*	  the CPU Interface+*  2) Sets the DRAM bar base and size by getting the base and size from+*     the CPU Interface when the size is the sum of all enabled DRAM +*	  chip selects and the base is the base of CS0 .+*  3) Sets the Device bar base and size by getting these values from the +*     CPU Interface when the base is the base of the lowest base of the+*     Device chip selects, and the +*+*+* INPUT:+*+*       pexIf   -  PEX interface number.+*+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM+*+*******************************************************************************/+MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)+{+	MV_U32 	       		bar;+	MV_U32		   	winNum;+	MV_PEX_BAR	  	pexBar;+	MV_PEX_DEC_WIN 		pexWin;+	MV_CPU_DEC_WIN 		addrDecWin;+	MV_TARGET 		target;+	MV_U32			pexCurrWin=0;+	MV_U32			status;+	/* default and exapntion rom +	are always configured */++#ifndef MV_DISABLE_PEX_DEVICE_BAR+	MV_U32		   	winIndex;+	MV_U32 		    	maxBase=0, sizeOfMaxBase=0;+	MV_U32			pexStartWindow;+#endif++	/* Parameter checking   */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}+	+	/* Enabled CPU access to PCI-Express */+	mvCpuIfEnablePex(pexIf, pexType);++    /* Start with bars */+	/* First disable all PEX bars*/+	for (bar = 0; bar < PEX_MAX_BARS; bar++)+    {+		if (PEX_INTER_REGS_BAR != bar)+		{+			if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))+			{+				mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);+				return MV_ERROR;+			}+			+		}++	}++	/* and disable all PEX target windows  */+	for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)+    {+		if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))+		{+			mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",+					   winNum);+			return MV_ERROR;++		}+	}++	/* Now, go through all bars*/++++/******************************************************************************/+/*                       Internal registers bar                               */+/******************************************************************************/+	bar = PEX_INTER_REGS_BAR;++	/* we only open the bar , no need to open windows for this bar */++	/* first get the CS attribute from the CPU Interface */+	if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))+	{+		mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);+		return MV_ERROR;+	}++	pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;+	pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;+	pexBar.addrWin.size = addrDecWin.addrWin.size;+	pexBar.enable = MV_TRUE;++	if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))+	{+		mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);+		return MV_ERROR;+	}+	+/******************************************************************************/+/*                                DRAM bar                                    */+/******************************************************************************/++	bar = PEX_DRAM_BAR;++	pexBar.addrWin.size = 0;+	+	for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )+	{++		status = mvCpuIfTargetWinGet(target,&addrDecWin);++		if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))+		{+			continue;+		}++		/* first get attributes from CPU If */+		if (MV_OK != status)+		{+			mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);+			return MV_ERROR;+		}+		if (addrDecWin.enable == MV_TRUE)+		{				+			/* the base is the base of DRAM CS0 always */+			if (SDRAM_CS0 == target )+			{+				pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;+				pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;++			}++			/* increment the bar size to be the sum of the size of all+			DRAM chips selecs */+			pexBar.addrWin.size += addrDecWin.addrWin.size;++			/* set a Pex window for this target ! +			DRAM CS always will have a Pex Window , and is not a +			part of the priority table */+			pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;+			pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;+			pexWin.addrWin.size = addrDecWin.addrWin.size;+			+			/* we disable the windows at first because we are not+			sure that it is witihin bar boundries */+			pexWin.enable =MV_FALSE;+			pexWin.target = target;+			pexWin.targetBar = bar;++			if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))+			{+				mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");+				return MV_ERROR;+			}+		}+	}++	/* check if the size of the bar is illeggal */+	if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))+	{+		/* try to get a good size */+		pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,+												 PXBCR_BAR_SIZE_ALIGNMENT);+	}+    +	/* check if the size and base are valid */+	if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))+	{+		mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);+		mvOsPrintf("it will be disabled\n");+		mvOsPrintf("please check Pex and CPU windows configuration\n");+	}+	else+	{+		pexBar.enable = MV_TRUE;+        +		/* configure the bar */+		if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))+		{+			mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);+			return MV_ERROR;+		}+	+		/* after the bar was configured then we enable the Pex windows*/+		for (winNum = 0;winNum < pexCurrWin ;winNum++)+		{+			if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))+			{+				mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);+				return MV_ERROR;+			}+	+		}+	}++/******************************************************************************/+/*                              DEVICE bar                                    */+/******************************************************************************/++/* Open the Device BAR for non linux only */+#ifndef MV_DISABLE_PEX_DEVICE_BAR ++	/* then device  bar*/+	bar = PEX_DEVICE_BAR;++	/* save the starting window */+	pexStartWindow = pexCurrWin;+	pexBar.addrWin.size = 0;+	pexBar.addrWin.baseLow = 0xffffffff;+	pexBar.addrWin.baseHigh = 0;+	maxBase = 0;++	for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )+	{+		status = mvCpuIfTargetWinGet(target,&addrDecWin);++		if (MV_NO_SUCH == status)+		{+			continue;+		}++		if (MV_OK != status)+		{+			mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);+			return MV_ERROR;+		}++		if (addrDecWin.enable == MV_TRUE)+		{				+			/* get the minimum base */+			if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)+			{+				pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;+			}++			/* get the maximum base */+			if (addrDecWin.addrWin.baseLow > maxBase)+			{+				maxBase = addrDecWin.addrWin.baseLow;+				sizeOfMaxBase = addrDecWin.addrWin.size;+			}++			/* search in the priority table for this target */+			for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;+				 winIndex++)+			{+				if (pexDevBarPrioTable[winIndex] != target)+				{+					continue;+				}+				else if (pexDevBarPrioTable[winIndex] == target)+				{+					/*found it */++					/* if the index of this target in the prio table is valid +					then we set the Pex window for this target, a valid index is +					an index that is lower than the number of the windows that+					was not configured yet */++					/* we subtract 2 always because the default and expantion+					rom windows are always configured */+					if ( pexCurrWin  < PEX_MAX_TARGET_WIN - 2)+					{+						/* set a Pex window for this target !  */+						pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;+						pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;+						pexWin.addrWin.size = addrDecWin.addrWin.size;+						+						/* we disable the windows at first because we are not+						sure that it is witihin bar boundries */+						pexWin.enable = MV_FALSE;+						pexWin.target = target;+						pexWin.targetBar = bar;++						if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,+													   &pexWin))+						{+							mvOsPrintf("mvPexInit: ERR. Window Set failed\n");+							return MV_ERROR;+						}+					}+				}+			}+		}+	}++	pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;+	pexBar.enable = MV_TRUE;++	/* check if the size of the bar is illegal */+	if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))+	{+		/* try to get a good size */+		pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,+												 PXBCR_BAR_SIZE_ALIGNMENT);+	}++	/* check if the size and base are valid */+	if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))+	{+		mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);+		mvOsPrintf("it will be disabled\n");+		mvOsPrintf("please check Pex and CPU windows configuration\n");+	}+	else+	{+		if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))+		{+			mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);+			return MV_ERROR;+		}++		/* now enable the windows */+		for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)+		{+			if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))+			{+				mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",+						   winNum);+				return MV_ERROR;+			}+		}+	}++#endif++	return mvPexHalInit(pexIf, pexType);++}++/*******************************************************************************+* mvPexTargetWinSet - Set PEX to peripheral target address window BAR+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_OK if PEX BAR target window was set correctly, +*		MV_BAD_PARAM on bad params +*       MV_ERROR otherwise +*       (e.g. address window overlapps with other active PEX target window).+*+*******************************************************************************/+MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum, +                            MV_PEX_DEC_WIN *pAddrDecWin)+{++	MV_DEC_REGS decRegs;+	PEX_WIN_REG_INFO winRegInfo;+	MV_TARGET_ATTRIB targetAttribs;++	/* Parameter checking   */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}++	if (winNum >= PEX_MAX_TARGET_WIN)+	{+		mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);+		return MV_BAD_PARAM;++	}++	/* get the pex Window registers offsets */+	pexWinRegInfoGet(pexIf,winNum,&winRegInfo);+++	if (MV_TRUE == pAddrDecWin->enable)+	{++		/* 2) Check if the requested window overlaps with current windows  */+		if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))+		{+			mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);+			return MV_BAD_PARAM;+		}+	+		/* 2) Check if the requested window overlaps with current windows  */+		if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))+		{+			mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",+					   winNum);+			return MV_BAD_PARAM;+		}++	}++++	/* read base register*/+	+	if (winRegInfo.baseLowRegOffs)+	{+		decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);+	}+	else+	{+		decRegs.baseReg = 0;+	}++	if (winRegInfo.sizeRegOffs)+	{+		decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);+	}+	else+	{+		decRegs.sizeReg =0;+	}+	+	if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+	{+		mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");+		return MV_ERROR;		+	}++	/* enable\Disable */+	if (MV_TRUE == pAddrDecWin->enable)+	{+		decRegs.sizeReg |= PXWCR_WIN_EN;+	}+	else+	{+		decRegs.sizeReg &= ~PXWCR_WIN_EN;+	}+++	/* clear bit location */+	decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;++	/* set bar Mapping */+	if (pAddrDecWin->targetBar == 1)+	{+		decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;+	}+	else if (pAddrDecWin->targetBar == 2)+	{+		decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;+	}++	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);++	/* set attributes */+	decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;+	decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;+	/* set target ID */+	decRegs.sizeReg &= ~PXWCR_TARGET_MASK;+	decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;+++	/* 3) Write to address decode Base Address Register                   */++	if (winRegInfo.baseLowRegOffs)+	{+		MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);+	}++	/* write size reg */+	if (winRegInfo.sizeRegOffs)+	{+		if ((MV_PEX_WIN_DEFAULT == winNum)||+			(MV_PEX_WIN_EXP_ROM == winNum))+		{+			/* clear size because there is no size field*/+			decRegs.sizeReg &= ~PXWCR_SIZE_MASK;++			/* clear enable because there is no enable field*/+			decRegs.sizeReg &= ~PXWCR_WIN_EN;++		}++		MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);+	}+++    return MV_OK;++}++/*******************************************************************************+* mvPexTargetWinGet - Get PEX to peripheral target address window+*+* DESCRIPTION:+*		Get the PEX to peripheral target address window BAR.+*+* INPUT:+*       pexIf - PEX interface number.+*       bar   - BAR to be accessed by slave.+*+* OUTPUT:+*       pAddrBarWin - PEX target window information data structure.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum, +                            MV_PEX_DEC_WIN *pAddrDecWin)+{+	MV_TARGET_ATTRIB targetAttrib;+	MV_DEC_REGS decRegs;++	PEX_WIN_REG_INFO winRegInfo;++	/* Parameter checking   */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}++	if (winNum >= PEX_MAX_TARGET_WIN)+	{+		mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);+		return MV_BAD_PARAM;++	}++	/* get the pex Window registers offsets */+	pexWinRegInfoGet(pexIf,winNum,&winRegInfo);++	/* read base register*/+	if (winRegInfo.baseLowRegOffs)+	{+		decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);+	}+	else+	{+		decRegs.baseReg = 0;+	}++	/* read size reg */+	if (winRegInfo.sizeRegOffs)+	{+		decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);+	}+	else+	{+		decRegs.sizeReg =0;+	}++	if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))+	{+		mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");+		return MV_ERROR;++	}++	if (decRegs.sizeReg & PXWCR_WIN_EN)+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else+	{+		pAddrDecWin->enable = MV_FALSE;	  ++	}+++	#if 0+    if (-1 == pAddrDecWin->addrWin.size)+	{+		return MV_ERROR;+	}+	#endif+++	/* get target bar */+	if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )+	{+		pAddrDecWin->targetBar = 1;+	} +	else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == +			 PXWCR_WIN_BAR_MAP_BAR2 )+	{+		pAddrDecWin->targetBar = 2;+	}++	/* attrib and targetId */+	pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >> +													PXWCR_ATTRIB_OFFS;+	pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >> +													PXWCR_TARGET_OFFS;++	targetAttrib.attrib = pAddrDecWin->attrib;+	targetAttrib.targetId = pAddrDecWin->targetId;++	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++	return MV_OK;++}+++/*******************************************************************************+* mvPexTargetWinEnable - Enable/disable a PEX BAR window+*+* DESCRIPTION:+*       This function enable/disable a PEX BAR window.+*       if parameter 'enable' == MV_TRUE the routine will enable the +*       window, thus enabling PEX accesses for that BAR (before enabling the +*       window it is tested for overlapping). Otherwise, the window will +*       be disabled.+*+* INPUT:+*       pexIf  - PEX interface number.+*       bar    - BAR to be accessed by slave.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)+{+	PEX_WIN_REG_INFO winRegInfo;+	MV_PEX_DEC_WIN addrDecWin;++	/* Parameter checking   */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);+		return MV_BAD_PARAM;+	}++	if (winNum >= PEX_MAX_TARGET_WIN)+	{+		mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);+		return MV_BAD_PARAM;++	}+++	/* get the pex Window registers offsets */+	pexWinRegInfoGet(pexIf,winNum,&winRegInfo);+++	/* if the address windows is disabled , we only disable the appropriare+	pex window and ignore other settings */++	if (MV_FALSE == enable)+	{++		/* this is not relevant to default and expantion rom+		windows */+		if (winRegInfo.sizeRegOffs)+		{+			if ((MV_PEX_WIN_DEFAULT != winNum)&&+				(MV_PEX_WIN_EXP_ROM != winNum))+			{+				MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);+			}+		}++	}+	else+	{+		if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))+		{+			mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");+			return MV_ERROR;+		}++		/* Check if the requested window overlaps with current windows	*/+		if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))+		{+			mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);+			return MV_BAD_PARAM;+		}++		if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))+		{+			mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",+					   winNum);+			return MV_BAD_PARAM;+		}+++		/* this is not relevant to default and expantion rom+		windows */+		if (winRegInfo.sizeRegOffs)+		{+			if ((MV_PEX_WIN_DEFAULT != winNum)&&+				(MV_PEX_WIN_EXP_ROM != winNum))+			{+				MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);+			}+		}+++	}++	return MV_OK;++}++++/*******************************************************************************+* mvPexTargetWinRemap - Set PEX to target address window remap.+*+* DESCRIPTION:+*       The PEX interface supports remap of the BAR original address window.+*       For each BAR it is possible to define a remap address. For example+*       an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified+*       according to remap register but will also be targeted to the +*       SDRAM CS[0].+*+* INPUT:+*       pexIf    - PEX interface number.+*       bar      - Peripheral target enumerator accessed by slave.+*       pAddrWin - Address window to be checked.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum, +                           MV_PEX_REMAP_WIN *pAddrWin)+{++	PEX_WIN_REG_INFO winRegInfo;+	+	/* Parameter checking   */+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n", +																		pexIf);+		return MV_BAD_PARAM;+	}+	if (MV_PEX_WIN_DEFAULT == winNum)+	{+		mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n", +																		winNum);+		return MV_BAD_PARAM;++	}++	if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))+	{+		mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\+				   "\nAddress 0x%08x is unaligned to size 0x%x.\n",+				   pexIf,+				   winNum,+                   pAddrWin->addrWin.baseLow,+				   pAddrWin->addrWin.size);+		+		return MV_ERROR;+	}++	pexWinRegInfoGet(pexIf, winNum, &winRegInfo);++	/* Set remap low register value */+	MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);+	+	/* Skip base high settings if the BAR has only base low (32-bit)		*/+	if (0 != winRegInfo.remapHighRegOffs)+	{+		MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);+	}+++	if (pAddrWin->enable == MV_TRUE)+	{+		MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);+	}+	else+	{+		MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);+	}++	return MV_OK;+}++/*******************************************************************************+* mvPexTargetWinRemapEnable - +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/++MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum, +                           MV_BOOL enable)+{+	PEX_WIN_REG_INFO winRegInfo;+	+	/* Parameter checking   */+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n", +																		pexIf);+		return MV_BAD_PARAM;+	}+	if (MV_PEX_WIN_DEFAULT == winNum)+	{+		mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n", +																		winNum);+		return MV_BAD_PARAM;++	}+++	pexWinRegInfoGet(pexIf, winNum, &winRegInfo);++	if (enable == MV_TRUE)+	{+		MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);+	}+	else+	{+		MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);+	}++	return MV_OK;++}++/*******************************************************************************+*  mvPexBarSet - Set PEX bar address and size +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexBarSet(MV_U32 pexIf,+						MV_U32 barNum,+						MV_PEX_BAR *pAddrWin)+{+	MV_U32 regBaseLow;+	MV_U32 regSize,sizeToReg;+++	/* check parameters */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}++	if(barNum >= PEX_MAX_BARS)+	{+		mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);+		return MV_BAD_PARAM;+	}+	++	if (pAddrWin->addrWin.size == 0)+	{+		mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );+		return MV_BAD_PARAM;+	}+++	/* Check if the window complies with PEX spec							*/+	if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,+								 pAddrWin->addrWin.size))+	{+        mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);+		return MV_BAD_PARAM;+	}++    /* 2) Check if the requested bar overlaps with current bars		*/+    if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))+	{+        mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);+		return MV_BAD_PARAM;+	}++	/* Get size register value according to window size						*/+	sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);+	+	/* Read bar size */+	if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */+	{+		regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));++		/* Size parameter validity check.                                   */+		if (-1 == sizeToReg)+		{+			mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);+			return MV_BAD_PARAM;+		}+	+		regSize &= ~PXBCR_BAR_SIZE_MASK;+		regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;+	+		MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);++	}++	/* set size */++++	/* Read base address low */+	regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,+												   PEX_MV_BAR_BASE(barNum)));++	/* clear current base */+	if (PEX_INTER_REGS_BAR == barNum)+	{+		regBaseLow &= ~PXBIR_BASE_MASK;+        regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);+	}+	else+	{+		regBaseLow &= ~PXBR_BASE_MASK;+		regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);+	}++	/* if we had a previous value that contain the bar type (MeM\IO), we want to+	restore it */+	regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;++++	/* write base low */+    MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),+				regBaseLow);++	if (pAddrWin->addrWin.baseHigh != 0)+	{+		/* Read base address high */+		MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),+								 pAddrWin->addrWin.baseHigh);++	}++	/* lastly enable the Bar */+	if (pAddrWin->enable == MV_TRUE)+	{+		if (PEX_INTER_REGS_BAR != barNum) /* internal registers +												are enabled always */+		{+			MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);+		}+	}+	else if (MV_FALSE == pAddrWin->enable)+	{+		if (PEX_INTER_REGS_BAR != barNum) /* internal registers +												are enabled always */+		{+			MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);+		}++	}++++	return MV_OK;+}+++/*******************************************************************************+*  mvPexBarGet - Get PEX bar address and size+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/++MV_STATUS mvPexBarGet(MV_U32 pexIf,+								MV_U32 barNum,+								MV_PEX_BAR *pAddrWin)+{+	/* check parameters */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}++	if(barNum >= PEX_MAX_BARS)+	{+		mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);+		return MV_BAD_PARAM;+	}++	/* read base low */+	pAddrWin->addrWin.baseLow = +		MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));+++	if (PEX_INTER_REGS_BAR == barNum)+	{+		pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;+	}+	else+	{+		pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;+	}+++	/* read base high */+	pAddrWin->addrWin.baseHigh = +		MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));+++	/* Read bar size */+	if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */+	{+		pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));++		/* check if enable or not */+		if (pAddrWin->addrWin.size & PXBCR_BAR_EN)+		{+			pAddrWin->enable = MV_TRUE;+		}+		else+		{+			pAddrWin->enable = MV_FALSE;+		}+			+		/* now get the size */+		pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;+		pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;++		pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,+											   PXBCR_BAR_SIZE_ALIGNMENT);++	}+	else /* PEX_INTER_REGS_BAR */+	{+		pAddrWin->addrWin.size = INTER_REGS_SIZE;+		pAddrWin->enable = MV_TRUE;+	}+++	return MV_OK;+}++/*******************************************************************************+*  mvPexBarEnable - +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+++MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)+{++	MV_PEX_BAR pexBar;++	/* check parameters */+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}+++	if(barNum >= PEX_MAX_BARS)+	{+		mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);+		return MV_BAD_PARAM;+	}++    if (PEX_INTER_REGS_BAR == barNum)+	{+		if (MV_TRUE == enable)+		{+			return MV_OK;+		}+		else+		{+			return MV_ERROR;+		}+	}+++	if (MV_FALSE == enable)+	{+			/* disable bar and quit */+			MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);+			return MV_OK;+	}++	/* else */++	if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)+	{+		mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");+		return MV_ERROR;++	}++	if (MV_TRUE == pexBar.enable)+	{+		/* it is already enabled !!! */+		return MV_OK;+	}++	/* else enable the bar*/++	pexBar.enable = MV_TRUE;++	if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)+	{+		mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");+		return MV_ERROR;++	}++	return MV_OK;+}+++/*******************************************************************************+* pexWinOverlapDetect - Detect address windows overlapping+*+* DESCRIPTION:+*       This function detects address window overlapping of a given address +*       window in PEX BARs.+*+* INPUT:+*       pAddrWin - Address window to be checked.+*       bar      - BAR to be accessed by slave.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,+									 MV_U32 winNum,+									 MV_ADDR_WIN *pAddrWin)+{+    MV_U32 		   win;+	MV_PEX_DEC_WIN addrDecWin;++	+	for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)+    {+        /* don't check our target or illegal targets */+        if (winNum == win)+        {+            continue;+        }+        +		/* Get window parameters 	*/+		if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))+		{+			mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",+					   win);+            return MV_ERROR;+		}++		/* Do not check disabled windows	*/+		if (MV_FALSE == addrDecWin.enable)+		{+			continue;+		}++        +        if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))+		{                    +			mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n", +															winNum, win);+			return MV_TRUE;           +		}+    }+    +	return MV_FALSE;+}++/*******************************************************************************+* pexIsWinWithinBar - Detect if address is within PEX bar boundries+*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,+								   MV_ADDR_WIN *pAddrWin)+{+    MV_U32 		   bar;+	MV_PEX_BAR addrDecWin;++	for(bar = 0; bar < PEX_MAX_BARS; bar++)+    {+        +		/* Get window parameters 	*/+		if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))+		{+			mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");+            return MV_ERROR;+		}+		+		/* Do not check disabled bars	*/+		if (MV_FALSE == addrDecWin.enable)+		{+			continue;+		}++        +        if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))+		{                    +			return MV_TRUE;+		}+    }+    +	return MV_FALSE;++}++/*******************************************************************************+* pexBarOverlapDetect - Detect address windows overlapping+*+* DESCRIPTION:+*       This function detects address window overlapping of a given address +*       window in PEX BARs.+*+* INPUT:+*       pAddrWin - Address window to be checked.+*       bar      - BAR to be accessed by slave.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,+									 MV_U32 barNum,+									 MV_ADDR_WIN *pAddrWin)+{+    MV_U32 		   bar;+	MV_PEX_BAR barDecWin;++	+	for(bar = 0; bar < PEX_MAX_BARS; bar++)+    {+        /* don't check our target or illegal targets */+        if (barNum == bar)+        {+            continue;+        }+        +		/* Get window parameters 	*/+		if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))+		{+			mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");+            return MV_ERROR;+		}++		/* don'nt check disabled bars */+        if (barDecWin.enable == MV_FALSE)+		{+			continue;+		}+++        if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))+		{                    +			mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n", +															barNum, bar);+			return MV_TRUE;           +		}+    }+    +	return MV_FALSE;+}++/*******************************************************************************+* pexBarIsValid - Check if the given address window is valid+*+* DESCRIPTION:+*		PEX spec restrict BAR base to be aligned to BAR size.+*		This function checks if the given address window is valid.+*+* INPUT:+*       baseLow - 32bit low base address.+*       size    - Window size.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the address window is valid, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)+{++	/* PCI spec restrict BAR base to be aligned to BAR size					*/+	if(MV_IS_NOT_ALIGN(baseLow, size))+	{+		return MV_ERROR;+	}+	else+	{+		return MV_TRUE;+	}+	+	return MV_TRUE;+}++/*******************************************************************************+* pexBarRegInfoGet - Get BAR register information+*+* DESCRIPTION:+* 		PEX BARs registers offsets are inconsecutive. +*		This function gets a PEX BAR register information like register offsets+*		and function location of the BAR.+*+* INPUT:+*       pexIf - PEX interface number.+*		bar	  - The PEX BAR in question.	+*+* OUTPUT:+*       pBarRegInfo - BAR register info struct.+*+* RETURN:+*		MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK+*+*******************************************************************************/+static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, +								  MV_U32 winNum,+								  PEX_WIN_REG_INFO *pWinRegInfo)+{++	if ((winNum >= 0)&&(winNum <=3))+	{+		pWinRegInfo->baseLowRegOffs   = PEX_WIN0_3_BASE_REG(pexIf,winNum);+		pWinRegInfo->baseHighRegOffs  = 0;+		pWinRegInfo->sizeRegOffs      = PEX_WIN0_3_CTRL_REG(pexIf,winNum);+		pWinRegInfo->remapLowRegOffs  = PEX_WIN0_3_REMAP_REG(pexIf,winNum);+		pWinRegInfo->remapHighRegOffs = 0;+	}+	else if ((winNum >= 4)&&(winNum <=5))+	{+		pWinRegInfo->baseLowRegOffs   = PEX_WIN4_5_BASE_REG(pexIf,winNum);+		pWinRegInfo->baseHighRegOffs  = 0;+		pWinRegInfo->sizeRegOffs      = PEX_WIN4_5_CTRL_REG(pexIf,winNum);+		pWinRegInfo->remapLowRegOffs  = PEX_WIN4_5_REMAP_REG(pexIf,winNum);+		pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);++	}+	else if (MV_PEX_WIN_DEFAULT == winNum)+	{+		pWinRegInfo->baseLowRegOffs   = 0;+		pWinRegInfo->baseHighRegOffs  = 0;+		pWinRegInfo->sizeRegOffs      = PEX_WIN_DEFAULT_CTRL_REG(pexIf);+		pWinRegInfo->remapLowRegOffs  = 0;+		pWinRegInfo->remapHighRegOffs = 0;+	}+	else if (MV_PEX_WIN_EXP_ROM == winNum)+	{+		pWinRegInfo->baseLowRegOffs   = 0;+		pWinRegInfo->baseHighRegOffs  = 0;+		pWinRegInfo->sizeRegOffs      = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);+		pWinRegInfo->remapLowRegOffs  = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);+		pWinRegInfo->remapHighRegOffs = 0;++	}++	return MV_OK;+}++/*******************************************************************************+* pexBarNameGet - Get the string name of PEX BAR.+*+* DESCRIPTION:+*		This function get the string name of PEX BAR.+*+* INPUT:+*       bar - PEX bar number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       pointer to the string name of PEX BAR.+*+*******************************************************************************/+const MV_8* pexBarNameGet( MV_U32 bar )+{+	switch( bar ) +	{+		case PEX_INTER_REGS_BAR: +			return "Internal Regs Bar0....";+		case PEX_DRAM_BAR: +			return "DRAM Bar1.............";+		case PEX_DEVICE_BAR: +			return "Devices Bar2..........";+		default:+			 return "Bar unknown";+	}+}+/*******************************************************************************+* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).+*+* DESCRIPTION:+*		This function print the PEX address decode map (BARs and windows).+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvPexAddrDecShow(MV_VOID)+{+	MV_PEX_BAR pexBar;+	MV_PEX_DEC_WIN win;+	MV_U32 pexIf;+	MV_U32 bar,winNum;++	for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )+	{+		if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;+		mvOsOutput( "\n" );+		mvOsOutput( "PEX%d:\n", pexIf );+		mvOsOutput( "-----\n" );++		mvOsOutput( "\nPex Bars \n\n");++		for( bar = 0; bar < PEX_MAX_BARS; bar++ ) +		{+			memset( &pexBar, 0, sizeof(MV_PEX_BAR) );++			mvOsOutput( "%s ", pexBarNameGet(bar) );++			if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )+			{+				if( pexBar.enable )+				{+                    mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );+                    mvSizePrint( pexBar.addrWin.size );+                    mvOsOutput( "\n" );+				}+				else+					mvOsOutput( "disable\n" );+			}+		}+		mvOsOutput( "\nPex Decode Windows\n\n");++		for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)+		{+			memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );++			mvOsOutput( "win%d - ", winNum );++			if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)+			{+				if (win.enable)+				{+					mvOsOutput( "%s base %08x, ",+					mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );+					mvOsOutput( "...." );+					mvSizePrint( win.addrWin.size );++					mvOsOutput( "\n" );+				}+				else+					mvOsOutput( "disable\n" );+++			}+		}+	+		memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );++		mvOsOutput( "default win - " );++		if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)+		{+			mvOsOutput( "%s ",+			mvCtrlTargetNameGet(win.target) );+			mvOsOutput( "\n" );+		}+		memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );++		mvOsOutput( "Expansion ROM - " );++		if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)+		{+			mvOsOutput( "%s ",+			mvCtrlTargetNameGet(win.target) );+			mvOsOutput( "\n" );+		}++	}+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h	2010-11-09 20:28:08.372495456 +0100@@ -0,0 +1,348 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCSysPEXH+#define __INCSysPEXH++#include "mvCommon.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++/* 4KB granularity */+#define MINIMUM_WINDOW_SIZE     0x1000+#define MINIMUM_BAR_SIZE        0x1000+#define MINIMUM_BAR_SIZE_MASK	0xFFFFF000+#define BAR_SIZE_OFFS			12+#define BAR_SIZE_MASK			(0xFFFFF << BAR_SIZE_OFFS)++++#define MV_PEX_WIN_DEFAULT		6+#define MV_PEX_WIN_EXP_ROM		7+#define PEX_MAX_TARGET_WIN		8+++#define PEX_MAX_BARS			3+#define PEX_INTER_REGS_BAR		0+#define PEX_DRAM_BAR			1+#define PEX_DEVICE_BAR			2++/*************************************/+/* PCI Express BAR Control Registers */+/*************************************/+#define PEX_BAR_CTRL_REG(pexIf,bar)		(0x41804 + (bar-1)*4- (pexIf)*0x10000)+#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf)	(0x4180C - (pexIf)*0x10000)+++/* PCI Express BAR Control Register */+/* PEX_BAR_CTRL_REG (PXBCR) */++#define PXBCR_BAR_EN				BIT0+#define PXBCR_BAR_SIZE_OFFS			16+#define PXBCR_BAR_SIZE_MASK			(0xffff << PXBCR_BAR_SIZE_OFFS)+#define PXBCR_BAR_SIZE_ALIGNMENT	0x10000++++/* PCI Express Expansion ROM BAR Control Register */+/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */++#define PXERBCR_EXPROM_EN			BIT0+#define PXERBCR_EXPROMSZ_OFFS		19+#define PXERBCR_EXPROMSZ_MASK		(0xf << PXERBCR_EXPROMSZ_OFFS)+#define PXERBCR_EXPROMSZ_512KB		(0x0 << PXERBCR_EXPROMSZ_OFFS)+#define PXERBCR_EXPROMSZ_1024KB		(0x1 << PXERBCR_EXPROMSZ_OFFS)+#define PXERBCR_EXPROMSZ_2048KB		(0x3 << PXERBCR_EXPROMSZ_OFFS)+#define PXERBCR_EXPROMSZ_4096KB		(0x7 << PXERBCR_EXPROMSZ_OFFS)++/************************************************/+/* PCI Express Address Window Control Registers */+/************************************************/+#define PEX_WIN0_3_CTRL_REG(pexIf,winNum)       \+                                (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)+#define PEX_WIN0_3_BASE_REG(pexIf,winNum)       \+                                (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)+#define PEX_WIN0_3_REMAP_REG(pexIf,winNum)      \+                                (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)+#define PEX_WIN4_5_CTRL_REG(pexIf,winNum)       \+                            (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)+#define PEX_WIN4_5_BASE_REG(pexIf,winNum)       \+                            (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)+#define PEX_WIN4_5_REMAP_REG(pexIf,winNum)      \+                            (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)+#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \+                            (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)++#define PEX_WIN_DEFAULT_CTRL_REG(pexIf)         (0x418B0 - (pexIf) * 0x10000)+#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf)         (0x418C0 - (pexIf) * 0x10000)+#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf)        (0x418C4 - (pexIf) * 0x10000)++/* PCI Express Window Control Register */+/* PEX_WIN_CTRL_REG (PXWCR) */++#define	PXWCR_WIN_EN					BIT0 /* Window Enable.*/++#define	PXWCR_WIN_BAR_MAP_OFFS			1    /* Mapping to BAR.*/+#define	PXWCR_WIN_BAR_MAP_MASK			BIT1+#define	PXWCR_WIN_BAR_MAP_BAR1			(0 << PXWCR_WIN_BAR_MAP_OFFS)+#define	PXWCR_WIN_BAR_MAP_BAR2			(1 << PXWCR_WIN_BAR_MAP_OFFS)++#define	PXWCR_TARGET_OFFS				4  /*Unit ID */+#define	PXWCR_TARGET_MASK				(0xf << PXWCR_TARGET_OFFS)++#define	PXWCR_ATTRIB_OFFS				8  /* target attributes */+#define	PXWCR_ATTRIB_MASK				(0xff << PXWCR_ATTRIB_OFFS)++#define	PXWCR_SIZE_OFFS					16 /* size */+#define	PXWCR_SIZE_MASK					(0xffff << PXWCR_SIZE_OFFS)+#define	PXWCR_SIZE_ALIGNMENT			0x10000++/* PCI Express Window Base Register */+/* PEX_WIN_BASE_REG (PXWBR)*/++#define PXWBR_BASE_OFFS					16 /* address[31:16] */+#define PXWBR_BASE_MASK					(0xffff << PXWBR_BASE_OFFS)+#define PXWBR_BASE_ALIGNMENT			0x10000++/* PCI Express Window Remap Register */+/* PEX_WIN_REMAP_REG (PXWRR)*/++#define PXWRR_REMAP_EN					BIT0+#define PXWRR_REMAP_OFFS				16+#define PXWRR_REMAP_MASK				(0xffff << PXWRR_REMAP_OFFS)+#define PXWRR_REMAP_ALIGNMENT			0x10000++/* PCI Express Window Remap (High) Register */+/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/++#define PXWRHR_REMAP_HIGH_OFFS			0+#define PXWRHR_REMAP_HIGH_MASK			(0xffffffff << PXWRHR_REMAP_HIGH_OFFS)++/* PCI Express Default Window Control Register */+/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */++#define	PXWDCR_TARGET_OFFS				4  /*Unit ID */+#define	PXWDCR_TARGET_MASK				(0xf << PXWDCR_TARGET_OFFS)+#define	PXWDCR_ATTRIB_OFFS				8  /* target attributes */+#define	PXWDCR_ATTRIB_MASK				(0xff << PXWDCR_ATTRIB_OFFS)++/* PCI Express Expansion ROM Window Control Register */+/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/++#define	PXWERCR_TARGET_OFFS				4  /*Unit ID */+#define	PXWERCR_TARGET_MASK				(0xf << PXWERCR_TARGET_OFFS)+#define	PXWERCR_ATTRIB_OFFS				8  /* target attributes */+#define	PXWERCR_ATTRIB_MASK				(0xff << PXWERCR_ATTRIB_OFFS)++/* PCI Express Expansion ROM Window Remap Register */+/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/++#define PXWERRR_REMAP_EN				BIT0+#define PXWERRR_REMAP_OFFS				16+#define PXWERRR_REMAP_MASK				(0xffff << PXWERRR_REMAP_OFFS)+#define PXWERRR_REMAP_ALIGNMENT			0x10000++++/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/ +/* PCI Express BAR0 Internal Register*/+/*PEX BAR0_INTER_REG (PXBIR)*/++#define PXBIR_IOSPACE			BIT0	/* Memory Space Indicator */++#define PXBIR_TYPE_OFFS			1	   /* BAR Type/Init Val. */ +#define PXBIR_TYPE_MASK			(0x3 << PXBIR_TYPE_OFFS)+#define PXBIR_TYPE_32BIT_ADDR	(0x0 << PXBIR_TYPE_OFFS)+#define PXBIR_TYPE_64BIT_ADDR	(0x2 << PXBIR_TYPE_OFFS)++#define PXBIR_PREFETCH_EN		BIT3 	/* Prefetch Enable */++#define PXBIR_BASE_OFFS		20		/* Base address. Address bits [31:20] */+#define PXBIR_BASE_MASK		(0xfff << PXBIR_BASE_OFFS)+#define PXBIR_BASE_ALIGNMET	(1 << PXBIR_BASE_OFFS)+++/* PCI Express BAR0 Internal (High) Register*/+/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/      ++#define PXBIRH_BASE_OFFS			0		/* Base address. Bits [63:32] */+#define PXBIRH_BASE_MASK			(0xffffffff << PBBHR_BASE_OFFS)+++#define PEX_BAR_DEFAULT_ATTRIB		0xc /* Memory - Prefetch - 64 bit address */+#define PEX_BAR0_DEFAULT_ATTRIB	    PEX_BAR_DEFAULT_ATTRIB  +#define PEX_BAR1_DEFAULT_ATTRIB		PEX_BAR_DEFAULT_ATTRIB+#define PEX_BAR2_DEFAULT_ATTRIB		PEX_BAR_DEFAULT_ATTRIB+++/* PCI Express BAR1 Register */+/*  PCI Express BAR2 Register*/+/*PEX BAR1_REG (PXBR)*/+/*PEX BAR2_REG (PXBR)*/++#define PXBR_IOSPACE			BIT0	/* Memory Space Indicator */++#define PXBR_TYPE_OFFS			1	   /* BAR Type/Init Val. */ +#define PXBR_TYPE_MASK			(0x3 << PXBR_TYPE_OFFS)+#define PXBR_TYPE_32BIT_ADDR	(0x0 << PXBR_TYPE_OFFS)+#define PXBR_TYPE_64BIT_ADDR	(0x2 << PXBR_TYPE_OFFS)++#define PXBR_PREFETCH_EN		BIT3 	/* Prefetch Enable */++#define PXBR_BASE_OFFS		16		/* Base address. Address bits [31:16] */+#define PXBR_BASE_MASK		(0xffff << PXBR_BASE_OFFS)+#define PXBR_BASE_ALIGNMET	(1 << PXBR_BASE_OFFS)+++/* PCI Express BAR1 (High) Register*/+/* PCI Express BAR2 (High) Register*/+/*PEX BAR1_REG_HIGH (PXBRH)*/+/*PEX BAR2_REG_HIGH (PXBRH)*/++#define PXBRH_BASE_OFFS			0		/* Base address. Address bits [63:32] */+#define PXBRH_BASE_MASK			(0xffffffff << PXBRH_BASE_OFFS)++/* PCI Express Expansion ROM BAR Register*/+/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/++#define PXERBAR_EXPROMEN		BIT0	/* Expansion ROM Enable */++#define PXERBAR_BASE_512K_OFFS		19		/* Expansion ROM Base Address */+#define PXERBAR_BASE_512K_MASK		(0x1fff << PXERBAR_BASE_512K_OFFS) 	++#define PXERBAR_BASE_1MB_OFFS		20		/* Expansion ROM Base Address */+#define PXERBAR_BASE_1MB_MASK		(0xfff << PXERBAR_BASE_1MB_OFFS) 	++#define PXERBAR_BASE_2MB_OFFS		21		/* Expansion ROM Base Address */+#define PXERBAR_BASE_2MB_MASK		(0x7ff << PXERBAR_BASE_2MB_OFFS) 	++#define PXERBAR_BASE_4MB_OFFS		22		/* Expansion ROM Base Address */+#define PXERBAR_BASE_4MB_MASK		(0x3ff << PXERBAR_BASE_4MB_OFFS) 	++/* PEX Bar attributes */+typedef struct _mvPexBar+{+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */++}MV_PEX_BAR;++/* PEX Remap Window attributes */+typedef struct _mvPexRemapWin+{+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */++}MV_PEX_REMAP_WIN;++/* PEX Remap Window attributes */+typedef struct _mvPexDecWin+{+	MV_TARGET	  target;+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_U32		  targetBar;+	MV_U8			attrib;			/* chip select attributes */+	MV_TARGET_ID 	targetId; 		/* Target Id of this MV_TARGET */+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */++}MV_PEX_DEC_WIN;++/* Global Functions prototypes */+/* mvPexHalInit - Initialize PEX interfaces*/+MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);+++/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/+MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum, +                            MV_PEX_DEC_WIN *pAddrDecWin);++/* mvPexTargetWinGet - Get PEX to peripheral target address window*/+MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum, +                            MV_PEX_DEC_WIN *pAddrDecWin);++/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/+MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);++/* mvPexTargetWinRemap - Set PEX to target address window remap.*/+MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum, +                           MV_PEX_REMAP_WIN *pAddrWin);++/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/+MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum, +                           MV_BOOL enable);++/* mvPexBarSet - Set PEX bar address and size */+MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);++/* mvPexBarGet - Get PEX bar address and size */+MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);++/* mvPexBarEnable - enable\disable a PEX bar*/+MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);++/* mvPexAddrDecShow - Display address decode windows attributes */+MV_VOID mvPexAddrDecShow(MV_VOID);++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c	2010-11-09 20:28:08.402495399 +0100@@ -0,0 +1,430 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#include "mvTypes.h"+#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "cpu/mvCpu.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "sata/CoreDriver/mvRegs.h"+#include "ctrlEnv/sys/mvSysSata.h"++MV_TARGET sataAddrDecPrioTab[] =+{+#if defined(MV_INCLUDE_SDRAM_CS0)+    SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+    SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+    SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+    SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_PEX)+	PEX0_MEM,+#endif+	TBL_TERM+};+++/*******************************************************************************+* sataWinOverlapDetect - Detect SATA address windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviur is expected in case SATA address decode +*       windows overlapps.+*       This function detects SATA address decode windows overlapping of a +*       specified window. The function does not check the window itself for +*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data +*       from registers.+*+*******************************************************************************/+static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum, +				      MV_ADDR_WIN *pAddrWin)+{+    MV_U32          winNumIndex;+    MV_SATA_DEC_WIN  addrDecWin;++    for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)+    {+        /* Do not check window itself       */+        if (winNumIndex == winNum)+        {+            continue;+        }++        /* Get window parameters    */+        if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))+        {+            mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);+            return MV_ERROR;+        }++        /* Do not check disabled windows    */+        if(addrDecWin.enable == MV_FALSE)+        {+            continue;+        }++        if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+        {+            return MV_TRUE;+        }        +    }+    return MV_FALSE;+}+++/*******************************************************************************+* mvSataWinSet - Set SATA target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) +*       address window, also known as address decode window. +*       After setting this target window, the SATA will be able to access the +*       target within the address window. +*+* INPUT:+*       winNum      - SATA target address decode window number.+*       pAddrDecWin - SATA target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if address window overlapps with other address decode windows.+*       MV_BAD_PARAM if base address is invalid parameter or target is +*       unknown.+*+*******************************************************************************/+MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)+{+    MV_TARGET_ATTRIB    targetAttribs;+    MV_DEC_REGS         decRegs;++    /* Parameter checking   */+    if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);+        return MV_BAD_PARAM;+    }+    +    /* Check if the requested window overlapps with current windows         */+    if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))+    {+        mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);+        return MV_ERROR;+    }++    /* check if address is aligned to the size */+    if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+    {+	mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\+		   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+		   winNum,+		   mvCtrlTargetNameGet(pAddrDecWin->target), +		   pAddrDecWin->addrWin.baseLow,+		   pAddrDecWin->addrWin.size);+	return MV_ERROR;+    }++    decRegs.baseReg = 0;+    decRegs.sizeReg = 0;++    if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+    {+        mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);+        return MV_ERROR;+    }++    mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);+                                                                                                                         +    /* set attributes */+    decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;+    decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);++    /* set target ID */+    decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;+    decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);++    if (pAddrDecWin->enable == MV_TRUE)+    {+        decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;+    }+    else+    {+        decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;+    }++    MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);+    MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);+    +    return MV_OK;+}++/*******************************************************************************+* mvSataWinGet - Get SATA peripheral target address window.+*+* DESCRIPTION:+*       Get SATA peripheral target address window.+*+* INPUT:+*       winNum - SATA target address decode window number.+*+* OUTPUT:+*       pAddrDecWin - SATA target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)+{+    MV_DEC_REGS         decRegs;+    MV_TARGET_ATTRIB    targetAttrib;+                                                                                                                         +    /* Parameter checking   */+    if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n", +                    __FUNCTION__, dev, winNum);+        return MV_NOT_SUPPORTED;+    }++    decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );+    decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );+ +    if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )+    {+        mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);+        return MV_ERROR; +    }+       +    /* attrib and targetId */+    targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >> +		MV_SATA_WIN_ATTR_OFFSET;+    targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >> +		MV_SATA_WIN_TARGET_OFFSET;+ +    pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++    /* Check if window is enabled   */+    if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK) +    {+        pAddrDecWin->enable = MV_TRUE;+    }+    else+    {+        pAddrDecWin->enable = MV_FALSE;+    }+    return MV_OK;+}+/*******************************************************************************+* mvSataAddrDecShow - Print the SATA address decode map.+*+* DESCRIPTION:+*		This function print the SATA address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvSataAddrDecShow(MV_VOID)+{++	MV_SATA_DEC_WIN win;+	int i,j;++++    for( j = 0; j < MV_SATA_MAX_CHAN; j++ )+    {+	if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j)) +		return;++	mvOsOutput( "\n" );+	mvOsOutput( "SATA %d:\n", j );+	mvOsOutput( "----\n" );++	for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )+	{+            memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );++	    mvOsOutput( "win%d - ", i );++	    if( mvSataWinGet(j, i, &win ) == MV_OK )+	    {+	        if( win.enable )+	        {+                    mvOsOutput( "%s base %08x, ",+                    mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );+                    mvOsOutput( "...." );++                    mvSizePrint( win.addrWin.size );+    +		    mvOsOutput( "\n" );+                }+		else+		mvOsOutput( "disable\n" );+	    }+	}+    }+}+++/*******************************************************************************+* mvSataWinInit - Initialize the integrated SATA target address window.+*+* DESCRIPTION:+*       Initialize the SATA peripheral target address window.+*+* INPUT:+*+*+* OUTPUT:+*     +*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvSataWinInit(MV_VOID)+{+    int             winNum;+    MV_SATA_DEC_WIN  sataWin;+    MV_CPU_DEC_WIN  cpuAddrDecWin;+    MV_U32          status, winPrioIndex = 0;++    /* Initiate Sata address decode */++    /* First disable all address decode windows */+    for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)+    {+        MV_U32  regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));+        regVal &= ~MV_SATA_WIN_ENABLE_MASK;+        MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);+    }+    +    winNum = 0;+    while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&+           (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )+    {+        /* first get attributes from CPU If */+        status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],+                                     &cpuAddrDecWin);++        if(MV_NO_SUCH == status)+        {+            winPrioIndex++;+            continue;+        }+	if (MV_OK != status)+	{+            mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);+	    return MV_ERROR;+	}++        if (cpuAddrDecWin.enable == MV_TRUE)+        {+            sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+            sataWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow;+            sataWin.addrWin.size     = cpuAddrDecWin.addrWin.size;+            sataWin.enable           = MV_TRUE;+            sataWin.target           = sataAddrDecPrioTab[winPrioIndex];+            +            if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))+            {+                return MV_ERROR;+            }+            winNum++;+        }+        winPrioIndex++;+    }+    return MV_OK;+}+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h	2010-11-09 20:28:08.526524216 +0100@@ -0,0 +1,128 @@++/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#ifndef __INCMVSysSataAddrDech+#define __INCMVSysSataAddrDech++#include "mvCommon.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/sys/mvCpuIf.h"+++#ifdef __cplusplus+extern "C" {+#endif++typedef struct _mvSataDecWin+{+    MV_TARGET     target;+    MV_ADDR_WIN   addrWin;    /* An address window*/+    MV_BOOL       enable;     /* Address decode window is enabled/disabled    */+ +} MV_SATA_DEC_WIN;+++#define MV_SATA_MAX_ADDR_DECODE_WIN 4++#define MV_SATA_WIN_CTRL_REG(dev, win)        (SATA_REG_BASE + 0x30 + ((win)<<4))+#define MV_SATA_WIN_BASE_REG(dev, win)        (SATA_REG_BASE + 0x34 + ((win)<<4))++/* BITs in Bridge Interrupt Cause and Mask registers */+#define MV_SATA_ADDR_DECODE_ERROR_BIT        0+#define MV_SATA_ADDR_DECODE_ERROR_MASK       (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)++/* BITs in Windows 0-3 Control and Base Registers */+#define MV_SATA_WIN_ENABLE_BIT               0+#define MV_SATA_WIN_ENABLE_MASK              (1<<MV_SATA_WIN_ENABLE_BIT)++#define MV_SATA_WIN_TARGET_OFFSET            4+#define MV_SATA_WIN_TARGET_MASK              (0xF<<MV_SATA_WIN_TARGET_OFFSET)++#define MV_SATA_WIN_ATTR_OFFSET              8+#define MV_SATA_WIN_ATTR_MASK                (0xFF<<MV_SATA_WIN_ATTR_OFFSET)++#define MV_SATA_WIN_SIZE_OFFSET              16+#define MV_SATA_WIN_SIZE_MASK                (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)++#define MV_SATA_WIN_BASE_OFFSET              16+#define MV_SATA_WIN_BASE_MASK                (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)++MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);+MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);+MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);+MV_STATUS mvSataWinInit(MV_VOID);+MV_VOID   mvSataAddrDecShow(MV_VOID);+++#ifdef __cplusplus+}+#endif+++#endif+++++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c	2010-11-09 20:28:08.633445891 +0100@@ -0,0 +1,427 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#include "mvTypes.h"+#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "cpu/mvCpu.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "mvRegs.h"+#include "ctrlEnv/sys/mvSysSdmmc.h"++MV_TARGET sdmmcAddrDecPrioTab[] =+{+#if defined(MV_INCLUDE_SDRAM_CS0)+    SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+    SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+    SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+    SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_PEX)+	PEX0_MEM,+#endif+	TBL_TERM+};+++/*******************************************************************************+* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviur is expected in case SDMMC address decode +*       windows overlapps.+*       This function detects SDMMC address decode windows overlapping of a +*       specified window. The function does not check the window itself for +*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data +*       from registers.+*+*******************************************************************************/+static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum, +				      MV_ADDR_WIN *pAddrWin)+{+    MV_U32          winNumIndex;+    MV_SDMMC_DEC_WIN  addrDecWin;++    for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)+    {+        /* Do not check window itself       */+        if (winNumIndex == winNum)+        {+            continue;+        }++        /* Get window parameters    */+        if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))+        {+            mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);+            return MV_ERROR;+        }++        /* Do not check disabled windows    */+        if(addrDecWin.enable == MV_FALSE)+        {+            continue;+        }++        if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+        {+            return MV_TRUE;+        }        +    }+    return MV_FALSE;+}+++/*******************************************************************************+* mvSdmmcWinSet - Set SDMMC target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) +*       address window, also known as address decode window. +*       After setting this target window, the SDMMC will be able to access the +*       target within the address window. +*+* INPUT:+*       winNum      - SDMMC target address decode window number.+*       pAddrDecWin - SDMMC target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if address window overlapps with other address decode windows.+*       MV_BAD_PARAM if base address is invalid parameter or target is +*       unknown.+*+*******************************************************************************/+MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)+{+    MV_TARGET_ATTRIB    targetAttribs;+    MV_DEC_REGS         decRegs;++    /* Parameter checking   */+    if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);+        return MV_BAD_PARAM;+    }+    +    /* Check if the requested window overlapps with current windows         */+    if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))+    {+        mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);+        return MV_ERROR;+    }++    /* check if address is aligned to the size */+    if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+    {+	mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\+		   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+		   winNum,+		   mvCtrlTargetNameGet(pAddrDecWin->target), +		   pAddrDecWin->addrWin.baseLow,+		   pAddrDecWin->addrWin.size);+	return MV_ERROR;+    }++    decRegs.baseReg = 0;+    decRegs.sizeReg = 0;++    if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+    {+        mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);+        return MV_ERROR;+    }++    mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);+                                                                                                                         +    /* set attributes */+    decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;+    decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);++    /* set target ID */+    decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;+    decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);++    if (pAddrDecWin->enable == MV_TRUE)+    {+        decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;+    }+    else+    {+        decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;+    }++    MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);+    MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);+    +    return MV_OK;+}++/*******************************************************************************+* mvSdmmcWinGet - Get SDMMC peripheral target address window.+*+* DESCRIPTION:+*       Get SDMMC peripheral target address window.+*+* INPUT:+*       winNum - SDMMC target address decode window number.+*d+* OUTPUT:+*       pAddrDecWin - SDMMC target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)+{+    MV_DEC_REGS         decRegs;+    MV_TARGET_ATTRIB    targetAttrib;+                                                                                                                         +    /* Parameter checking   */+    if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n", +                    __FUNCTION__, dev, winNum);+        return MV_NOT_SUPPORTED;+    }++    decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );+    decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );+ +    if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )+    {+        mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);+        return MV_ERROR; +    }+       +    /* attrib and targetId */+    targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >> +		MV_SDMMC_WIN_ATTR_OFFSET;+    targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >> +		MV_SDMMC_WIN_TARGET_OFFSET;+ +    pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++    /* Check if window is enabled   */+    if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK) +    {+        pAddrDecWin->enable = MV_TRUE;+    }+    else+    {+        pAddrDecWin->enable = MV_FALSE;+    }+    return MV_OK;+}+/*******************************************************************************+* mvSdmmcAddrDecShow - Print the SDMMC address decode map.+*+* DESCRIPTION:+*		This function print the SDMMC address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvSdmmcAddrDecShow(MV_VOID)+{++	MV_SDMMC_DEC_WIN win;+	int i,j=0;++++	if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0)) +		return;++	mvOsOutput( "\n" );+	mvOsOutput( "SDMMC %d:\n", j );+	mvOsOutput( "----\n" );++	for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )+	{+            memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );++	    mvOsOutput( "win%d - ", i );++	    if( mvSdmmcWinGet(j, i, &win ) == MV_OK )+	    {+	        if( win.enable )+	        {+                    mvOsOutput( "%s base %08x, ",+                    mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );+                    mvOsOutput( "...." );++                    mvSizePrint( win.addrWin.size );+    +		    mvOsOutput( "\n" );+                }+		else+		mvOsOutput( "disable\n" );+	    }+	}+}+++/*******************************************************************************+* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.+*+* DESCRIPTION:+*       Initialize the SDMMC peripheral target address window.+*+* INPUT:+*+*+* OUTPUT:+*     +*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvSdmmcWinInit(MV_VOID)+{+    int             winNum;+    MV_SDMMC_DEC_WIN  sdmmcWin;+    MV_CPU_DEC_WIN  cpuAddrDecWin;+    MV_U32          status, winPrioIndex = 0;++    /* Initiate Sdmmc address decode */++    /* First disable all address decode windows */+    for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)+    {+        MV_U32  regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));+        regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;+        MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);+    }+    +    winNum = 0;+    while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&+           (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )+    {+        /* first get attributes from CPU If */+        status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],+                                     &cpuAddrDecWin);++        if(MV_NO_SUCH == status)+        {+            winPrioIndex++;+            continue;+        }+	if (MV_OK != status)+	{+            mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);+	    return MV_ERROR;+	}++        if (cpuAddrDecWin.enable == MV_TRUE)+        {+            sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+            sdmmcWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow;+            sdmmcWin.addrWin.size     = cpuAddrDecWin.addrWin.size;+            sdmmcWin.enable           = MV_TRUE;+            sdmmcWin.target           = sdmmcAddrDecPrioTab[winPrioIndex];+            +            if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))+            {+                return MV_ERROR;+            }+            winNum++;+        }+        winPrioIndex++;+    }+    return MV_OK;+}+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h	2010-11-09 20:28:08.891243103 +0100@@ -0,0 +1,125 @@++/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#ifndef __INCMVSysSdmmcAddrDech+#define __INCMVSysSdmmcAddrDech++#include "mvCommon.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/sys/mvCpuIf.h"+++#ifdef __cplusplus+extern "C" {+#endif++typedef struct _mvSdmmcDecWin+{+    MV_TARGET     target;+    MV_ADDR_WIN   addrWin;    /* An address window*/+    MV_BOOL       enable;     /* Address decode window is enabled/disabled    */+ +} MV_SDMMC_DEC_WIN;+++#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4++#define MV_SDMMC_WIN_CTRL_REG(dev, win)        (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))+#define MV_SDMMC_WIN_BASE_REG(dev, win)        (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))+++/* BITs in Windows 0-3 Control and Base Registers */+#define MV_SDMMC_WIN_ENABLE_BIT               0+#define MV_SDMMC_WIN_ENABLE_MASK              (1<<MV_SDMMC_WIN_ENABLE_BIT)++#define MV_SDMMC_WIN_TARGET_OFFSET            4+#define MV_SDMMC_WIN_TARGET_MASK              (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)++#define MV_SDMMC_WIN_ATTR_OFFSET              8+#define MV_SDMMC_WIN_ATTR_MASK                (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)++#define MV_SDMMC_WIN_SIZE_OFFSET              16+#define MV_SDMMC_WIN_SIZE_MASK                (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)++#define MV_SDMMC_WIN_BASE_OFFSET              16+#define MV_SDMMC_WIN_BASE_MASK                (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)++MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);+MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);+MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);+MV_STATUS mvSdmmcWinInit(MV_VOID);+MV_VOID   mvSdmmcAddrDecShow(MV_VOID);+++#ifdef __cplusplus+}+#endif+++#endif+++++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c	2010-11-09 20:28:09.164485759 +0100@@ -0,0 +1,462 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvSysTdm.h"+++/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif	++static MV_TARGET tdmAddrDecPrioTap[] =+{+        PEX0_MEM,+        SDRAM_CS0,+        SDRAM_CS1,+        SDRAM_CS2,+        SDRAM_CS3,+        DEVICE_CS0,+        DEVICE_CS1,+        DEVICE_CS2,+        DEV_BOOCS,+        PEX0_IO,+        TBL_TERM+};++static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);++/*******************************************************************************+* mvTdmWinInit - Initialize TDM address decode windows +*+* DESCRIPTION:+*               This function initialize TDM window decode unit. It set the +*               default address decode+*               windows of the unit.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if setting fail.+*******************************************************************************/++MV_STATUS mvTdmWinInit(void)+{+	MV_U32 		winNum;+	MV_U32		winPrioIndex = 0;+	MV_CPU_DEC_WIN cpuAddrDecWin;+	MV_TDM_DEC_WIN tdmWin;+	MV_STATUS status;++	/*Disable all windows*/	+	for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)+	{+		mvTdmWinEnable(winNum, MV_FALSE);+	}++	for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) && +					  (winNum < TDM_MBUS_MAX_WIN)); )+	{	+		status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex], +									 &cpuAddrDecWin);+        if (MV_NO_SUCH == status)+        {+            winPrioIndex++;+            continue;+        }+		if (MV_OK != status)+		{+			mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");+			return MV_ERROR;+		}++        if (cpuAddrDecWin.enable == MV_TRUE)+		{+			tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+			tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;+			tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;+			tdmWin.enable = MV_TRUE;+		    tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];+		    if (MV_OK != mvTdmWinSet(winNum, &tdmWin))+		    {+			    return MV_ERROR;+		    }+		    winNum++;+		}+		winPrioIndex++;			+    }+	return MV_OK;+}++/*******************************************************************************+* mvTdmWinSet - Set TDM target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)+*       address window, also known as address decode window.+*       After setting this target window, the TDM will be able to access the+*       target within the address window.+*+* INPUT:+*       winNum      - TDM to target address decode window number.+*       pAddrDecWin - TDM target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if address window overlapps with other address decode windows.+*       MV_BAD_PARAM if base address is invalid parameter or target is+*       unknown.+*+*******************************************************************************/++MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)+{+	MV_TARGET_ATTRIB targetAttribs;+	MV_DEC_REGS decRegs;+	MV_U32 ctrlReg = 0;++    /* Parameter checking   */+    if (winNum >= TDM_MBUS_MAX_WIN)+    {+		mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);+        return MV_BAD_PARAM;+    }+    +    /* Check if the requested window overlapps with current windows         */+    if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))+   	{+       	mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);+		return MV_ERROR;+	}++	/* check if address is aligned to the size */+	if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+	{+		mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\+				   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+				   winNum,+				   mvCtrlTargetNameGet(pAddrDecWin->target), +				   pAddrDecWin->addrWin.baseLow,+				   pAddrDecWin->addrWin.size);+		return MV_ERROR;+	}++	decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));+	decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >>  TDM_WIN_SIZE_OFFS;++	if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+	{+			mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");+			return MV_ERROR;+	}+	+	mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);+	+	/* for the safe side we disable the window before writing the new+	values */+	mvTdmWinEnable(winNum, MV_FALSE);++	ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);+	ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);+	ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);++	/* Write to address base and control registers  */+	MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);+	MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);  +	/* Enable address decode target window  */+	if (pAddrDecWin->enable == MV_TRUE)+	{+		mvTdmWinEnable(winNum, MV_TRUE);+	}    +	return MV_OK;+}++/*******************************************************************************+* mvTdmWinGet - Get peripheral target address window.+*+* DESCRIPTION:+*               Get TDM peripheral target address window.+*+* INPUT:+*       winNum - TDM to target address decode window number.+*+* OUTPUT:+*       pAddrDecWin - TDM target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/++MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)+{++	MV_DEC_REGS decRegs;+	MV_TARGET_ATTRIB targetAttrib;++	/* Parameter checking   */+	if (winNum >= TDM_MBUS_MAX_WIN)+	{+		mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);+		return MV_NOT_SUPPORTED;+	}+	+	decRegs.baseReg =  MV_REG_READ(TDM_WIN_BASE_REG(winNum));                                                                           +	decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >>  TDM_WIN_SIZE_OFFS;+ +	if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))+	{+		mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");+		return MV_ERROR;+	}+	 +	/* attrib and targetId */+	targetAttrib.attrib = +		(MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >>  TDM_WIN_ATTRIB_OFFS;+	targetAttrib.targetId = +		(MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >>  TDM_WIN_TARGET_OFFS;+	 +	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++	/* Check if window is enabled   */+	if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else+	{+		pAddrDecWin->enable = MV_FALSE;+	}+	+	return MV_OK;+}++/*******************************************************************************+* mvTdmWinEnable - Enable/disable a TDM to target address window+*+* DESCRIPTION:+*       This function enable/disable a TDM to target address window.+*       According to parameter 'enable' the routine will enable the+*       window, thus enabling TDM accesses (before enabling the window it is+*       tested for overlapping). Otherwise, the window will be disabled.+*+* INPUT:+*       winNum - TDM to target address decode window number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if decode window number was wrong or enabled window overlapps.+*+*******************************************************************************/+MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)+{+	MV_TDM_DEC_WIN addrDecWin;++	if (MV_TRUE == enable)+	{+		if (winNum >= TDM_MBUS_MAX_WIN)+		{+			mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);+			return MV_ERROR;+		}	+		+		/* First check for overlap with other enabled windows				*/+		/* Get current window */+		if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))+		{+			mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");+			return MV_ERROR;+		}+		/* Check for overlapping */+		if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))+		{+			/* No Overlap. Enable address decode target window */+			MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);+		}+		else+		{   /* Overlap detected	*/+			mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");+			return MV_ERROR;+		}+	}+	else+	{+		MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);	+	}+	return MV_OK;+}+++/*******************************************************************************+* tdmWinOverlapDetect - Detect TDM address windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviour is expected in case TDM address decode +*       windows overlapps.+*       This function detects TDM address decode windows overlapping of a +*       specified window. The function does not check the window itself for +*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data +*       from registers.+*+*******************************************************************************/+static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)+{+    MV_U32      	winNumIndex;+    MV_TDM_DEC_WIN  	addrDecWin;++    for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)+    {+		/* Do not check window itself		*/+        if (winNumIndex == winNum)+		{+			continue;+		}+		/* Do not check disabled windows	*/+		if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)+		{+			/* Get window parameters 	*/+			if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))+			{+				DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));+            		return MV_ERROR;+			}++			if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+			{+				return MV_TRUE;+			}        +		}+    }+	return MV_FALSE;+}++/*******************************************************************************+* mvTdmAddrDecShow - Print the TDM address decode map.+*+* DESCRIPTION:+*       This function print the TDM address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvTdmAddrDecShow(MV_VOID)+{+	MV_TDM_DEC_WIN win;+	int i;++	mvOsOutput( "\n" );+	mvOsOutput( "TDM:\n" );+	mvOsOutput( "----\n" );++	for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )+	{+		memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );++		mvOsOutput( "win%d - ", i );++		if (mvTdmWinGet(i, &win ) == MV_OK )+		{+			if( win.enable )+			{+                mvOsOutput( "%s base %08x, ",+                mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);+                mvOsOutput( "...." );+                mvSizePrint( win.addrWin.size );+				mvOsOutput( "\n" );+			}+			else+				mvOsOutput( "disable\n" );+		}+	}+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h	2010-11-09 20:28:09.471497270 +0100@@ -0,0 +1,106 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSysTdmh+#define __INCmvSysTdmh++#include "ctrlEnv/sys/mvCpuIf.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++typedef struct _mvTdmDecWin+{+        MV_TARGET     target;+        MV_ADDR_WIN   addrWin; /* An address window*/+        MV_BOOL       enable;  /* Address decode window is enabled/disabled */ +} MV_TDM_DEC_WIN;++MV_STATUS mvTdmWinInit(MV_VOID);+MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);+MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);+MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);+MV_VOID mvTdmAddrDecShow(MV_VOID);+++#define TDM_MBUS_MAX_WIN	4+#define TDM_WIN_CTRL_REG(win)	((TDM_REG_BASE + 0x4030) + (win<<4))+#define TDM_WIN_BASE_REG(win)	((TDM_REG_BASE +0x4034) + (win<<4))++/* TDM_WIN_CTRL_REG bits */+#define TDM_WIN_ENABLE_OFFS	0+#define TDM_WIN_ENABLE_MASK	(1<<TDM_WIN_ENABLE_OFFS)+#define TDM_WIN_ENABLE		1+#define TDM_WIN_TARGET_OFFS	4+#define TDM_WIN_TARGET_MASK	(0xf<<TDM_WIN_TARGET_OFFS)+#define TDM_WIN_ATTRIB_OFFS	8+#define TDM_WIN_ATTRIB_MASK	(0xff<<TDM_WIN_ATTRIB_OFFS)+#define TDM_WIN_SIZE_OFFS	16+#define TDM_WIN_SIZE_MASK	(0xffff<<TDM_WIN_SIZE_OFFS)++/* TDM_WIN_BASE_REG bits */+#define TDM_BASE_OFFS		16+#define TDM_BASE_MASK		(0xffff<<TDM_BASE_OFFS)++#endif /*__INCmvSysTdmh*/+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c	2010-11-09 20:28:09.721570932 +0100@@ -0,0 +1,591 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+	notice, this list of conditions and the following disclaimer in the+	documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+	used to endorse or promote products derived from this software without+	specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#include "ctrlEnv/sys/mvSysTs.h"+++typedef struct _mvTsuDecWin+{+        MV_TARGET     target;+        MV_ADDR_WIN   addrWin; /* An address window*/+        MV_BOOL       enable;  /* Address decode window is enabled/disabled */+ +}MV_TSU_DEC_WIN;+++MV_TARGET tsuAddrDecPrioTap[] =+{+#if defined(MV_INCLUDE_PEX)+        PEX0_MEM,+#endif+#if defined(MV_INCLUDE_PCI)+        PCI0_MEM,+#endif+#if defined(MV_INCLUDE_SDRAM_CS0)+        SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+        SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+        SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+        SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_DEVICE_CS0)+        DEVICE_CS0,+#endif+#if defined(MV_INCLUDE_DEVICE_CS1)+        DEVICE_CS1,+#endif+#if defined(MV_INCLUDE_DEVICE_CS2)+        DEVICE_CS2,+#endif+#if defined(MV_INCLUDE_DEVICE_CS3)+        DEVICE_CS3,+#endif+#if defined(MV_INCLUDE_PEX)+        PEX0_IO,+#endif+#if defined(MV_INCLUDE_PCI)+        PCI0_IO,+#endif+        TBL_TERM+};++static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);+static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);+static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);+MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);++/*******************************************************************************+* mvTsuWinInit+*+* DESCRIPTION:+* 	Initialize the TSU unit address decode windows.+*+* INPUT:+*       None.+* OUTPUT:+*	None.+* RETURN:+*       MV_OK	- on success,+*+*******************************************************************************/+MV_STATUS mvTsuWinInit(void)+{+	MV_U32          winNum, status, winPrioIndex=0;+	MV_TSU_DEC_WIN  tsuWin;+	MV_CPU_DEC_WIN  cpuAddrDecWin;++	/* First disable all address decode windows */+	for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)+	{+		MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),+				 TSU_WIN_CTRL_EN_MASK);+	}++	/* Go through all windows in user table until table terminator      */+	for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&+			 (winNum < TSU_MAX_DECODE_WIN));)+	{+		/* first get attributes from CPU If */+		status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],+					     &cpuAddrDecWin);++		if(MV_NO_SUCH == status)+		{+			winPrioIndex++;+			continue;+		}+		if(MV_OK != status)+		{+			mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");+			return MV_ERROR;+		}++		if (cpuAddrDecWin.enable == MV_TRUE)+		{+			tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+			tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;+			tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;+			tsuWin.enable = MV_TRUE;+			tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];++			if(MV_OK != mvTsuWinSet(winNum, &tsuWin))+			{+				mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",+					   winNum);+				return MV_ERROR;+			}+			winNum++;+		}+		winPrioIndex ++;+	}++	return MV_OK;+}+++/*******************************************************************************+* mvTsuWinSet+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)+*       address window, also known as address decode window.+*       After setting this target window, the TSU will be able to access the+*       target within the address window.+*+* INPUT:+*       winNum      - TSU to target address decode window number.+*       pAddrDecWin - TSU target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR	- if address window overlapps with other address decode +*			windows.+*       MV_BAD_PARAM	- if base address is invalid parameter or target is+*       		unknown.+*+*******************************************************************************/+MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)+{+	MV_TARGET_ATTRIB    targetAttribs;+	MV_DEC_REGS         decRegs;++	/* Parameter checking   */+	if(winNum >= TSU_MAX_DECODE_WIN)+	{+		mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);+		return MV_BAD_PARAM;+	}    ++	/* Check if the requested window overlapps with current windows     */+	if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))+	{+		mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);+		return MV_ERROR;+	}++	/* check if address is aligned to the size */+	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))+	{+		mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "+			   "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+			   winNum, mvCtrlTargetNameGet(pAddrDecWin->target),+			   pAddrDecWin->addrWin.baseLow,+			   pAddrDecWin->addrWin.size);+		return MV_ERROR;+	}++	decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));+	decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));+    +	if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))+	{+		mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");+		return MV_ERROR;+	}+    +	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);+    +	/* set attributes */+	decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;+	decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;+	/* set target ID */+	decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;+	decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;++	/* for the safe side we disable the window before writing the new */+	/* values */+	mvTsuWinEnable(winNum, MV_FALSE);+	MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);++	/* Write to address decode Size Register                            */+	MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);++	/* Enable address decode target window                              */+	if(pAddrDecWin->enable == MV_TRUE)+	{+		mvTsuWinEnable(winNum,MV_TRUE);+	}++	return MV_OK;+}+++/*******************************************************************************+* mvTsuWinGet+*+* DESCRIPTION:+*	Get TSU peripheral target address window.+*+* INPUT:+*	winNum - TSU to target address decode window number.+*+* OUTPUT:+*       pAddrDecWin - TSU target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)+{+	MV_DEC_REGS decRegs;+	MV_TARGET_ATTRIB targetAttrib;++	/* Parameter checking   */+	if(winNum >= TSU_MAX_DECODE_WIN)+	{+		mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);+		return MV_NOT_SUPPORTED;+	}++	decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));                                                                           +	decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));+ +	if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))+	{+		mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");+		return MV_ERROR;+	}++	/* attrib and targetId */+	targetAttrib.attrib = +		(decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;+	targetAttrib.targetId = +		(decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;++	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++	/* Check if window is enabled   */+	if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else+	{+		pAddrDecWin->enable = MV_FALSE;+	}+	+	return MV_OK;+}+++/*******************************************************************************+* mvTsuWinEnable+*+* DESCRIPTION:+*       This function enable/disable a TSU to target address window.+*       According to parameter 'enable' the routine will enable the+*       window, thus enabling TSU accesses (before enabling the window it is+*       tested for overlapping). Otherwise, the window will be disabled.+*+* INPUT:+*       winNum - TSU to target address decode window number.+*       enable - Enable / disable parameter.+*+* OUTPUT:+*       N/A+*+* RETURN:+*       MV_ERROR if decode window number was wrong or enabled window overlapps.+*+*******************************************************************************/+MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)+{+	MV_TSU_DEC_WIN addrDecWin;++	/* Parameter checking   */+	if(winNum >= TSU_MAX_DECODE_WIN)+	{+		mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);+		return MV_ERROR;+	}++	if(enable == MV_TRUE)+	{+		/* First check for overlap with other enabled windows   */+		/* Get current window.					*/+		if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))+		{+			mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");+			return MV_ERROR;+		}+		/* Check for overlapping.	*/+		if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))+		{+			/* No Overlap. Enable address decode target window   */+			MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),+				       TSU_WIN_CTRL_EN_MASK);+		}+		else+		{+			/* Overlap detected */+			mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");+			return MV_ERROR;+		}+	}+	else+	{+		/* Disable address decode target window */+		MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),+				 TSU_WIN_CTRL_EN_MASK);+	}+	return MV_OK;+}++/*******************************************************************************+* mvTsuWinTargetGet+*+* DESCRIPTION:+*	Get Window number associated with target+*+* INPUT:+*	target	- Target ID to get the window number for.+* OUTPUT:+*+* RETURN:+*       window number or 0xFFFFFFFF on error.+*+*******************************************************************************/+MV_U32  mvTsuWinTargetGet(MV_TARGET target)+{+	MV_TSU_DEC_WIN decWin;+	MV_U32 winNum;++	/* Check parameters */+	if(target >= MAX_TARGETS)+	{+		mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);+		return 0xffffffff;+	}++	for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)+	{+		if(mvTsuWinGet(winNum,&decWin) != MV_OK)+		{+			mvOsPrintf("mvTsuWinGet: window returned error\n");+			return 0xffffffff;+		}++		if (decWin.enable == MV_TRUE)+		{+			if(decWin.target == target)+			{+				return winNum;+			}+		}+	}+	return 0xFFFFFFFF;+}+++/*******************************************************************************+* tsuWinOverlapDetect+*+* DESCRIPTION:+*	Detect TSU address windows overlapping+*	An unpredicted behaviur is expected in case TSU address decode+*	windows overlapps.+*	This function detects TSU address decode windows overlapping of a+*	specified window. The function does not check the window itself for+*	overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data+*       from registers.+*+*******************************************************************************/+static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)+{+	MV_U32              ctrlReg;+	MV_U32              winNumIndex;+	MV_TSU_DEC_WIN      addrDecWin;++	for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)+	{+		/* Do not check window itself           */+		if(winNumIndex == winNum)+		{+			continue;+		}++		/* Do not check disabled windows        */+		ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));+		if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)+		{+			continue;+		}++		/* Get window parameters        */+		if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))+		{+			mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");+			return MV_ERROR;+		}++		if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+		{+			return MV_TRUE;+		}+	}+	return MV_FALSE;+}+++/*******************************************************************************+* mvTsuAddrDecShow+*+* DESCRIPTION:+*	Print the TSU address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+void mvTsuAddrDecShow(void)+{+	MV_TSU_DEC_WIN  win;+	int             i;++	if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0)) +		return;++	mvOsOutput( "\n" );+	mvOsOutput( "TSU:\n");+	mvOsOutput( "----\n" );++	for(i = 0; i < TSU_MAX_DECODE_WIN; i++)+	{+		memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));+		mvOsOutput( "win%d - ", i );++		if(mvTsuWinGet(i, &win ) == MV_OK )+		{+			if(win.enable == MV_TRUE)+			{+				mvOsOutput("%s base %08x, ",+					   mvCtrlTargetNameGet(win.target),+					   win.addrWin.baseLow);+				mvOsOutput( "...." );+				mvSizePrint(win.addrWin.size );+				mvOsOutput( "\n" );+			}+			else+			{+				mvOsOutput( "disable\n" );+			}+		}+	}+	return;+}+++/*******************************************************************************+* mvTsuInit+*+* DESCRIPTION:+* 	Initialize the TSU unit, and get unit out of reset.+*+* INPUT:+*       coreClock	- The core clock at which the TSU should operate.+*       mode		- The mode on configure the unit into (serial/parallel).+* 	memHandle	- Memory handle used for memory allocations.+* OUTPUT:+*	None.+* RETURN:+*       MV_OK	- on success,+*+*******************************************************************************/+MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,+	            void *osHandle)+{+	MV_STATUS status;++	status = mvTsuWinInit();+	if(status == MV_OK)+		status = mvTsuHalInit(coreClock,mode,osHandle);++	return status;+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h	2010-11-09 20:28:09.894776606 +0100@@ -0,0 +1,110 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSysTsh+#define __INCmvSysTsh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* includes */+#include "ts/mvTsu.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++#define TSU_MAX_DECODE_WIN	4+++/*******************************************/+/* TSU Windows Registers                   */+/*******************************************/+#define MV_TSU_WIN_CTRL_REG(win)	(TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)+#define MV_TSU_WIN_BASE_REG(win)	(TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)++/* TSU windows control register.		*/+#define TSU_WIN_CTRL_EN_MASK		(0x1 << 0)+#define TSU_WIN_CTRL_TARGET_OFFS	4+#define TSU_WIN_CTRL_TARGET_MASK	(0xF << TSU_WIN_CTRL_TARGET_OFFS)+#define TSU_WIN_CTRL_ATTR_OFFS		8+#define TSU_WIN_CTRL_ATTR_MASK		(0xFF << TSU_WIN_CTRL_ATTR_OFFS)+#define TSU_WIN_CTRL_SIZE_OFFS		16+#define TSU_WIN_CTRL_SIZE_MASK		(0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)++/* TSU windows base register.			*/+#define TSU_WIN_BASE_OFFS		16+#define TSU_WIN_BASE_MASK		(0xFFFF << TSU_WIN_BASE_OFFS)++MV_STATUS mvTsuWinInit(void);++void mvTsuAddrDecShow(void);+MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,+	            void *osHandle);++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvTsh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c	2010-11-09 20:28:09.932495382 +0100@@ -0,0 +1,497 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "ctrlEnv/sys/mvSysUsb.h"++MV_TARGET usbAddrDecPrioTab[] =+{+#if defined(MV_INCLUDE_SDRAM_CS0)+    SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+    SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+    SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+    SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)+    CRYPT_ENG,+#endif+#if defined(MV_INCLUDE_PEX)+    PEX0_MEM,+#endif+    TBL_TERM+};++++MV_STATUS   mvUsbInit(int dev, MV_BOOL isHost)+{+    MV_STATUS       status;++    status = mvUsbWinInit(dev);+    if(status != MV_OK)+        return status;++    return mvUsbHalInit(dev, isHost);+}+++/*******************************************************************************+* usbWinOverlapDetect - Detect USB address windows overlapping+*+* DESCRIPTION:+*       An unpredicted behaviur is expected in case USB address decode+*       windows overlapps.+*       This function detects USB address decode windows overlapping of a+*       specified window. The function does not check the window itself for+*       overlapping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data+*       from registers.+*+*******************************************************************************/+static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,+                                     MV_ADDR_WIN *pAddrWin)+{+    MV_U32          winNumIndex;+    MV_DEC_WIN      addrDecWin;++    for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)+    {+        /* Do not check window itself       */+        if (winNumIndex == winNum)+        {+            continue;+        }++        /* Get window parameters    */+        if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))+        {+            mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);+            return MV_ERROR;+        }++        /* Do not check disabled windows    */+        if(addrDecWin.enable == MV_FALSE)+        {+            continue;+        }++        if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+        {+            return MV_TRUE;+        }+    }+    return MV_FALSE;+}++/*******************************************************************************+* mvUsbWinSet - Set USB target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)+*       address window, also known as address decode window.+*       After setting this target window, the USB will be able to access the+*       target within the address window.+*+* INPUT:+*       winNum      - USB target address decode window number.+*       pAddrDecWin - USB target window data structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_ERROR if address window overlapps with other address decode windows.+*       MV_BAD_PARAM if base address is invalid parameter or target is+*       unknown.+*+*******************************************************************************/+MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)+{+    MV_DEC_WIN_PARAMS   winParams;+    MV_U32              sizeReg, baseReg;++    /* Parameter checking   */+    if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);+        return MV_BAD_PARAM;+    }++    /* Check if the requested window overlapps with current windows         */+    if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))+    {+        mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);+        return MV_ERROR;+    }++    /* check if address is aligned to the size */+    if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))+    {+        mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\+                   "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",+                   winNum,+                   mvCtrlTargetNameGet(pDecWin->target),+                   pDecWin->addrWin.baseLow,+                   pDecWin->addrWin.size);+        return MV_ERROR;+    }++    if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))+    {+        mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);+        return MV_ERROR;+    }++    /* set Size, Attributes and TargetID */+    sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |+               ((winParams.attrib   << MV_USB_WIN_ATTR_OFFSET)   & MV_USB_WIN_ATTR_MASK)   |+               ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));++#if defined(MV645xx) || defined(MV646xx)+    /* If window is DRAM with HW cache coherency, make sure bit2 is set */+    sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;++    if((MV_TARGET_IS_DRAM(pDecWin->target)) &&+       (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))+    {+        sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;+    }+    else+    {+        sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;+    }+#endif /* MV645xx || MV646xx */++    if (pDecWin->enable == MV_TRUE)+    {+        sizeReg |= MV_USB_WIN_ENABLE_MASK;+    }+    else+    {+        sizeReg &= ~MV_USB_WIN_ENABLE_MASK;+    }++    /* Update Base value  */+    baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);++    MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);+    MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);++    return MV_OK;+}++/*******************************************************************************+* mvUsbWinGet - Get USB peripheral target address window.+*+* DESCRIPTION:+*       Get USB peripheral target address window.+*+* INPUT:+*       winNum - USB target address decode window number.+*+* OUTPUT:+*       pDecWin - USB target window data structure.+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)+{+    MV_DEC_WIN_PARAMS   winParam;+    MV_U32              sizeReg, baseReg;++    /* Parameter checking   */+    if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)+    {+        mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",+                    __FUNCTION__, dev, winNum);+        return MV_NOT_SUPPORTED;+    }++    baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );+    sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );++   /* Check if window is enabled   */+    if(sizeReg & MV_USB_WIN_ENABLE_MASK)+    {+        pDecWin->enable = MV_TRUE;++        /* Extract window parameters from registers */+        winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;+        winParam.attrib   = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;+        winParam.size     = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;+        winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);++        /* Translate the decode window parameters to address decode struct */+        if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))+        {+            mvOsPrintf("Failed to translate register parameters to USB address" \+                       " decode window structure\n");+            return MV_ERROR;+        }+    }+    else+    {+        pDecWin->enable = MV_FALSE;+    }+    return MV_OK;+}++/*******************************************************************************+* mvUsbWinInit -+*+* INPUT:+*+* OUTPUT:+*+* RETURN:+*       MV_ERROR if register parameters are invalid.+*+*******************************************************************************/+MV_STATUS   mvUsbWinInit(int dev)+{+    MV_STATUS       status;+    MV_DEC_WIN      usbWin;+    MV_CPU_DEC_WIN  cpuAddrDecWin;+    int             winNum;+    MV_U32          winPrioIndex = 0;++    /* First disable all address decode windows */+    for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)+    {+        MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);+    }++    /* Go through all windows in user table until table terminator          */+    winNum = 0;+    while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&+           (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )+    {+        /* first get attributes from CPU If */+        status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],+                                     &cpuAddrDecWin);++        if(MV_NO_SUCH == status)+        {+            winPrioIndex++;+            continue;+        }+        if (MV_OK != status)+        {+            mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);+            return MV_ERROR;+        }++        if (cpuAddrDecWin.enable == MV_TRUE)+        {+            usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;+            usbWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow;+            usbWin.addrWin.size     = cpuAddrDecWin.addrWin.size;+            usbWin.enable           = MV_TRUE;+            usbWin.target           = usbAddrDecPrioTab[winPrioIndex];++#if defined(MV645xx) || defined(MV646xx)+            /* Get the default attributes for that target window */+            mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);+#endif /* MV645xx || MV646xx */++            if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))+            {+                return MV_ERROR;+            }+            winNum++;+        }+        winPrioIndex++;+    }+    return MV_OK;+}++/*******************************************************************************+* mvUsbAddrDecShow - Print the USB address decode map.+*+* DESCRIPTION:+*       This function print the USB address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvUsbAddrDecShow(MV_VOID)+{+    MV_DEC_WIN  addrDecWin;+    int         i, winNum;++    mvOsOutput( "\n" );+    mvOsOutput( "USB:\n" );+    mvOsOutput( "----\n" );++    for(i=0; i<mvCtrlUsbMaxGet(); i++)+    {+        mvOsOutput( "Device %d:\n", i);++        for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)+        {+            memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );++            mvOsOutput( "win%d - ", winNum );++            if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )+            {+                if( addrDecWin.enable )+                {+                    mvOsOutput( "%s base %08x, ",+                        mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );++                    mvSizePrint( addrDecWin.addrWin.size );++#if defined(MV645xx) || defined(MV646xx)+                    switch( addrDecWin.addrWinAttr.swapType)+                    {+                        case MV_BYTE_SWAP:+                            mvOsOutput( "BYTE_SWAP, " );+                            break;+                        case MV_NO_SWAP:+                            mvOsOutput( "NO_SWAP  , " );+                            break;+                        case MV_BYTE_WORD_SWAP:+                            mvOsOutput( "BYTE_WORD_SWAP, " );+                            break;+                        case MV_WORD_SWAP:+                            mvOsOutput( "WORD_SWAP, " );+                            break;+                        default:+                            mvOsOutput( "SWAP N/A , " );+                    }++                    switch( addrDecWin.addrWinAttr.cachePolicy )+                    {+                        case NO_COHERENCY:+                            mvOsOutput( "NO_COHERENCY , " );+                            break;+                        case WT_COHERENCY:+                            mvOsOutput( "WT_COHERENCY , " );+                            break;+                        case WB_COHERENCY:+                            mvOsOutput( "WB_COHERENCY , " );+                            break;+                        default:+                            mvOsOutput( "COHERENCY N/A, " );+                    }++                    switch( addrDecWin.addrWinAttr.pcixNoSnoop )+                    {+                        case 0:+                            mvOsOutput( "PCI-X NS inactive, " );+                            break;+                        case 1:+                            mvOsOutput( "PCI-X NS active  , " );+                            break;+                        default:+                            mvOsOutput( "PCI-X NS N/A     , " );+                    }++                    switch( addrDecWin.addrWinAttr.p2pReq64 )+                    {+                        case 0:+                            mvOsOutput( "REQ64 force" );+                            break;+                        case 1:+                            mvOsOutput( "REQ64 detect" );+                            break;+                        default:+                            mvOsOutput( "REQ64 N/A" );+                    }+#endif /* MV645xx || MV646xx */+                    mvOsOutput( "\n" );+                }+                else+                    mvOsOutput( "disable\n" );+            }+        }+    }+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h	2010-11-09 20:28:09.972495420 +0100@@ -0,0 +1,125 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSysUsbh+#define __INCmvSysUsbh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* includes */+#include "usb/mvUsb.h"+#include "ctrlEnv/sys/mvCpuIf.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++#define MV_USB_MAX_ADDR_DECODE_WIN  4++/*******************************************/+/* USB Bridge Registers                    */+/*******************************************/+#define MV_USB_BRIDGE_CTRL_REG(dev)              (USB_REG_BASE(dev) + 0x300)++#define MV_USB_WIN_CTRL_REG(dev, win)        (USB_REG_BASE(dev) + 0x320 + ((win)<<4)) +#define MV_USB_WIN_BASE_REG(dev, win)        (USB_REG_BASE(dev) + 0x324 + ((win)<<4))++/* BITs in Windows 0-3 Control and Base Registers */+#define MV_USB_WIN_ENABLE_BIT               0+#define MV_USB_WIN_ENABLE_MASK              (1 << MV_USB_WIN_ENABLE_BIT)++#define MV_USB_WIN_BURST_WR_LIMIT_BIT       1+#define MV_USB_WIN_BURST_WR_LIMIT_MASK      (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)+#define MV_USB_WIN_BURST_WR_NO_LIMIT        (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)+#define MV_USB_WIN_BURST_WR_32BIT_LIMIT     (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)++#define MV_USB_WIN_TARGET_OFFSET            4+#define MV_USB_WIN_TARGET_MASK              (0xF << MV_USB_WIN_TARGET_OFFSET)++#define MV_USB_WIN_ATTR_OFFSET              8+#define MV_USB_WIN_ATTR_MASK                (0xFF << MV_USB_WIN_ATTR_OFFSET)++#define MV_USB_WIN_SIZE_OFFSET              16+#define MV_USB_WIN_SIZE_MASK                (0xFFFF << MV_USB_WIN_SIZE_OFFSET)++#define MV_USB_WIN_BASE_OFFSET              16+#define MV_USB_WIN_BASE_MASK                (0xFFFF << MV_USB_WIN_BASE_OFFSET)+++#define MV_USB_BRIDGE_IPG_REG(dev)          (USB_REG_BASE(dev) + 0x360)+++MV_STATUS   mvUsbInit(int dev, MV_BOOL isHost);++MV_STATUS   mvUsbWinInit(int dev);+MV_STATUS   mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);+MV_STATUS   mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);++void        mvUsbAddrDecShow(void);++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvUsbh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c	2010-11-09 20:28:10.022500031 +0100@@ -0,0 +1,662 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "xor/mvXor.h"+#include "mvSysXor.h"++/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+#else+	#define DB(x)+#endif	+++static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);++MV_TARGET xorAddrDecPrioTap[] = +{+#if defined(MV_INCLUDE_DEVICE_CS0)+    DEVICE_CS0,+#endif+#if defined(MV_INCLUDE_PEX)+	PEX0_MEM,+#endif+#if defined(MV_INCLUDE_SDRAM_CS0)+    SDRAM_CS0,+#endif+#if defined(MV_INCLUDE_SDRAM_CS1)+    SDRAM_CS1,+#endif+#if defined(MV_INCLUDE_SDRAM_CS2)+    SDRAM_CS2,+#endif+#if defined(MV_INCLUDE_SDRAM_CS3)+    SDRAM_CS3,+#endif+#if defined(MV_INCLUDE_DEVICE_CS1)+    DEVICE_CS1,+#endif+#if defined(MV_INCLUDE_CESA)+   CRYPT_ENG,+#endif +	TBL_TERM+};+static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)+{+	MV_U32         winNum;+	MV_XOR_DEC_WIN addrDecWin;+	MV_CPU_DEC_WIN cpuAddrDecWin;+	MV_U32          status;+	MV_U32			winPrioIndex=0;++	/* Initiate XOR address decode */++	/* First disable all address decode windows */+	for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)+	{+	    mvXorTargetWinEnable(unit,winNum, MV_FALSE);+	}+	+	/* Go through all windows in user table until table terminator			*/+	for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&+					(winNum < XOR_MAX_ADDR_DEC_WIN));)+	{+		/* first get attributes from CPU If */+		status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex], +									 &cpuAddrDecWin);++        if(MV_NO_SUCH == status)+        {+            winPrioIndex++;+            continue;+        }+		if (MV_OK != status)+		{+            mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);+			return MV_ERROR;+		}++	+        if (cpuAddrDecWin.enable == MV_TRUE)+		{++			addrDecWin.target           = xorAddrDecPrioTap[winPrioIndex];+			addrDecWin.addrWin.baseLow  = cpuAddrDecWin.addrWin.baseLow; +			addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh; +			addrDecWin.addrWin.size     = cpuAddrDecWin.addrWin.size;    +			addrDecWin.enable           = MV_TRUE;+	+			if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))+			{+				DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));+				return MV_ERROR;+			}+			winNum++;+		}+		winPrioIndex++;	+        +	}+    +	return MV_OK;+}+++/*******************************************************************************+* mvXorInit - Initialize XOR engine+*+* DESCRIPTION:+*		This function initialize XOR unit. It set the default address decode+*		windows of the unit.+*		Note that if the address window is disabled in xorAddrDecMap, the+*		window parameters will be set but the window will remain disabled.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.+*******************************************************************************/+MV_STATUS mvXorInit (MV_VOID)+{+	MV_U32         i;++	/* Initiate XOR address decode */+	for(i = 0; i < MV_XOR_MAX_UNIT; i++)+	    mvXorInitWinsUnit(i);++	mvXorHalInit(MV_XOR_MAX_CHAN);	+    +	return MV_OK;+}++/*******************************************************************************+* mvXorTargetWinSet - Set XOR target address window+*+* DESCRIPTION:+*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) +*       address window. After setting this target window, the XOR will be +*       able to access the target within the address window. +*+* INPUT:+*	    winNum - One of the possible XOR memory decode windows.+*       target - Peripheral target enumerator.+*       base   - Window base address.+*       size   - Window size.+*       enable - Window enable/disable.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.+*+*******************************************************************************/+MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)+{+    MV_DEC_REGS xorDecRegs;+	MV_TARGET_ATTRIB targetAttribs;+    MV_U32      chan;+    +    /* Parameter checking */+    if (winNum >= XOR_MAX_ADDR_DEC_WIN)+    {+		DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));+        return MV_BAD_PARAM;+    }+    if (pAddrDecWin == NULL)+    {+        DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));+        return MV_BAD_PTR;+    }                                         +    /* Check if the requested window overlaps with current windows */+    if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))+    {+	DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));+	return MV_ERROR;+    }                              ++    xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));+    xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));++    /* Get Base Address and size registers values */+    if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))+    {+		DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));+        return MV_BAD_PARAM;+	}+    ++	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);++	/* set attributes */+	xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;+	xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;+	/* set target ID */+	xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;+	xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;+++    /* Write to address decode Base Address Register */+	MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);+    +    /* Write to Size Register */+	MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);+    +    for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)+    {+        if (pAddrDecWin->enable)+        {+            MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),+                           XEXWCR_WIN_EN_MASK(winNum));+        }+        else+        {+            MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),+                             XEXWCR_WIN_EN_MASK(winNum));+        }+    }+    return MV_OK;+}++/*******************************************************************************+* mvXorTargetWinGet - Get xor peripheral target address window.+*+* DESCRIPTION:+*		Get xor peripheral target address window.+*+* INPUT:+*	  winNum - One of the possible XOR memory decode windows.+*+* OUTPUT:+*       base   - Window base address.+*       size   - Window size.+*       enable - window enable/disable.+*+* RETURN:+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.+*+*******************************************************************************/+MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)+{+    MV_DEC_REGS xorDecRegs;+	MV_TARGET_ATTRIB targetAttrib;+    MV_U32      chan=0,chanWinEn;+    +    /* Parameter checking */+    if (winNum >= XOR_MAX_ADDR_DEC_WIN)+    {+		DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));+        return MV_ERROR;+    }++    if (NULL == pAddrDecWin)+    {+        DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));+        return MV_BAD_PTR;+    }++    chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);+    +    for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */+    {+    	/* Check if enable bit is equal for all channels */+        if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) & +             XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)+        {+            mvOsPrintf("%s: ERR. Window enable field must be equal in "+                              "all channels(chan=%d)\n",__FUNCTION__, chan);+            return MV_ERROR;+        }+    }++++	xorDecRegs.baseReg  = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));+	xorDecRegs.sizeReg  = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));++	if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))+	{+		mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);+		return MV_ERROR;+	}++	/* attrib and targetId */+	targetAttrib.attrib = +		(xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;+	targetAttrib.targetId = +		(xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;+++	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);++	if(chanWinEn)+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else pAddrDecWin->enable = MV_FALSE;+	+    return MV_OK;+}++/*******************************************************************************+* mvXorTargetWinEnable - Enable/disable a Xor address decode window+*+* DESCRIPTION:+*       This function enable/disable a XOR address decode window.+*       if parameter 'enable' == MV_TRUE the routine will enable the +*       window, thus enabling XOR accesses (before enabling the window it is +*       tested for overlapping). Otherwise, the window will be disabled.+*+* INPUT:+*       winNum - Decode window number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.+*+*******************************************************************************/+MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)+{+	MV_XOR_DEC_WIN  addrDecWin;+    MV_U32          chan;+    +	/* Parameter checking   */               +    if (winNum >= XOR_MAX_ADDR_DEC_WIN)+    {+        DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));+        return MV_ERROR;+    }++	if (enable == MV_TRUE) +	{+		/* Get current window */+	    if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))+		{+			DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));+			return MV_ERROR;+		}++		/* Check for overlapping */+	    if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))+		{+			/* Overlap detected	*/+			DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));+			return MV_ERROR;+		}++		/* No Overlap. Enable address decode target window */+		for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)+		{+		    MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),+						   XEXWCR_WIN_EN_MASK(winNum));+		}++	}+	else+	{+		/* Disable address decode target window */++		for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)+		{+		    MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),+							 XEXWCR_WIN_EN_MASK(winNum));+		}++	}++	return MV_OK;                  +}++/*******************************************************************************+* mvXorSetProtWinSet - Configure access attributes of a XOR engine+*                               to one of the XOR memory windows.+*+* DESCRIPTION:+*       Each engine can be configured with access attributes for each of the+*       memory spaces. This function sets access attributes +*       to a given window for the given engine+*+* INPUTS:+*       chan    - One of the possible engines.+*       winNum  - One of the possible XOR memory spaces.+*       access  - Protection access rights.+*       write   - Write rights.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.+*+*******************************************************************************/+MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access, +                           MV_BOOL write)+{+    MV_U32 temp;+    +    /* Parameter checking   */+    if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)+    {+		DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));+        return MV_BAD_PARAM;+    }+    if (winNum >= XOR_MAX_ADDR_DEC_WIN)+    {+		DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));+        return MV_BAD_PARAM;+    }++    temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) & +        (~XEXWCR_WIN_ACC_MASK(winNum));++    /* if access is disable */+    if (!access)+    {+        /* disable access */+        temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);+    }+    /* if access is enable */+    else+    {+        /* if write is enable */+        if (write)+        {+            /* enable write */+            temp |= XEXWCR_WIN_ACC_RW(winNum);+        }+        /* if write is disable */+        else+        {+            /* disable write */+            temp |= XEXWCR_WIN_ACC_RO(winNum);+        }+    }+    MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);+    return MV_OK;+}++/*******************************************************************************+* mvXorPciRemap - Set XOR remap register for PCI address windows.+*+* DESCRIPTION:+*       only Windows 0-3 can be remapped.+*+* INPUT:+*       winNum      - window number+*       pAddrDecWin  - pointer to address space window structure+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.+*+*******************************************************************************/+MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)+{+    /* Parameter checking   */+    if (winNum >= XOR_MAX_REMAP_WIN)+    {+		DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));+        return MV_BAD_PARAM;+    }++    MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);+    +	return MV_OK;+}++/*******************************************************************************+* xorWinOverlapDetect - Detect XOR address windows overlaping+*+* DESCRIPTION:+*       An unpredicted behaviour is expected in case XOR address decode +*       windows overlaps.+*       This function detects XOR address decode windows overlaping of a +*       specified window. The function does not check the window itself for +*       overlaping. The function also skipps disabled address decode windows.+*+* INPUT:+*       winNum      - address decode window number.+*       pAddrDecWin - An address decode window struct.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlap current address+*       decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data +*       from registers.+*+*******************************************************************************/+static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)+{+	MV_U32 	        baseAddrEnableReg;+	MV_U32          winNumIndex,chan;+	MV_XOR_DEC_WIN  addrDecWin;++	if (pAddrWin == NULL)+	{+		DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));+		return MV_BAD_PTR;+	}+    +	for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)+	{+		/* Read base address enable register. Do not check disabled windows	*/+	    baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));++		for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)+		{+			/* Do not check window itself */+			if (winNumIndex == winNum)+			{+				continue;+			}+    +			/* Do not check disabled windows */+			if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)+			{+				continue;+			}+    +			/* Get window parameters */+			if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))+			{+				DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));+				return MV_ERROR;+			}+            +			if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))+			{+				return MV_TRUE;+			}+		}+	}+	+	return MV_FALSE;+}++static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)+{+	MV_XOR_DEC_WIN win;+	int            i;++	mvOsOutput( "\n" );+	mvOsOutput( "XOR %d:\n", unit );+	mvOsOutput( "----\n" );++	for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )+	{+		memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );++		mvOsOutput( "win%d - ", i );++		if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )+		{+			if( win.enable )+			{+				mvOsOutput( "%s base %x, ",+				mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );++				mvSizePrint( win.addrWin.size );+				+                mvOsOutput( "\n" );+			}+			else+				mvOsOutput( "disable\n" );+		}+	}+}++/*******************************************************************************+* mvXorAddrDecShow - Print the XOR address decode map.+*+* DESCRIPTION:+*		This function print the XOR address decode map.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID mvXorAddrDecShow(MV_VOID)+{+	int            i;++	for( i = 0; i < MV_XOR_MAX_UNIT; i++ )+	    mvXorAddrDecShowUnit(i);+	+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h	2010-11-09 20:28:10.062495382 +0100@@ -0,0 +1,140 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCMVSysXorh+#define __INCMVSysXorh+++#ifdef __cplusplus+extern "C" {+#endif++#include "ctrlEnv/sys/mvCpuIf.h"++#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++#define XOR_MAX_ADDR_DEC_WIN	8	/* Maximum address decode windows		*/+#define XOR_MAX_REMAP_WIN       4	/* Maximum address arbiter windows		*/++/* XOR Engine Address Decoding Register Map */                  +#define XOR_WINDOW_CTRL_REG(unit,chan)     (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))+#define XOR_BASE_ADDR_REG(unit,winNum)     (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))+#define XOR_SIZE_MASK_REG(unit,winNum)     (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))+#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))++/* XOR Engine [0..1] Window Control Registers (XExWCR) */+#define XEXWCR_WIN_EN_OFFS(winNum)          (winNum)+#define XEXWCR_WIN_EN_MASK(winNum)          (1 << (XEXWCR_WIN_EN_OFFS(winNum)))+#define XEXWCR_WIN_EN_ENABLE(winNum)        (1 << (XEXWCR_WIN_EN_OFFS(winNum)))+#define XEXWCR_WIN_EN_DISABLE(winNum)       (0 << (XEXWCR_WIN_EN_OFFS(winNum)))++#define XEXWCR_WIN_ACC_OFFS(winNum)         ((2 * winNum) + 16)+#define XEXWCR_WIN_ACC_MASK(winNum)         (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))+#define XEXWCR_WIN_ACC_NO_ACC(winNum)       (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))+#define XEXWCR_WIN_ACC_RO(winNum)           (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))+#define XEXWCR_WIN_ACC_RW(winNum)           (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))++/* XOR Engine Base Address Registers (XEBARx) */+#define XEBARX_TARGET_OFFS                  (0)+#define XEBARX_TARGET_MASK                  (0xF << XEBARX_TARGET_OFFS)+#define XEBARX_ATTR_OFFS                    (8)+#define XEBARX_ATTR_MASK                    (0xFF << XEBARX_ATTR_OFFS)+#define XEBARX_BASE_OFFS                    (16)+#define XEBARX_BASE_MASK                    (0xFFFF << XEBARX_BASE_OFFS)++/* XOR Engine Size Mask Registers (XESMRx) */+#define XESMRX_SIZE_MASK_OFFS               (16)+#define XESMRX_SIZE_MASK_MASK               (0xFFFF << XESMRX_SIZE_MASK_OFFS)++/* XOR Engine High Address Remap Register (XEHARRx1) */+#define XEHARRX_REMAP_OFFS                  (0)+#define XEHARRX_REMAP_MASK                  (0xFFFFFFFF << XEHARRX_REMAP_OFFS)++typedef struct _mvXorDecWin+{+    MV_TARGET     target;+    MV_ADDR_WIN   addrWin; /* An address window*/+    MV_BOOL       enable;  /* Address decode window is enabled/disabled */+ +}MV_XOR_DEC_WIN;++MV_STATUS   mvXorInit (MV_VOID);+MV_STATUS   mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,+			      MV_XOR_DEC_WIN *pAddrDecWin);+MV_STATUS   mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,+			      MV_XOR_DEC_WIN *pAddrDecWin);+MV_STATUS   mvXorTargetWinEnable(MV_U32 unit, +			      MV_U32 winNum, MV_BOOL enable);+MV_STATUS   mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access, +                             MV_BOOL write);+MV_STATUS   mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);++MV_VOID     mvXorAddrDecShow(MV_VOID);++#ifdef __cplusplus+}+#endif++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c	2010-11-09 20:28:10.101392611 +0100@@ -0,0 +1,75 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "device/mvDevice.h"++/* defines  */       +#ifdef MV_DEBUG         +	#define DB(x)	x+#else                +	#define DB(x)    +#endif	             +++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h	2010-11-09 20:28:10.141918633 +0100@@ -0,0 +1,74 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDeviceH+#define __INCmvDeviceH++#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "device/mvDeviceRegs.h"+++#endif /* #ifndef __INCmvDeviceH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h	2010-11-09 20:28:10.181250318 +0100@@ -0,0 +1,101 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDeviceRegsH+#define __INCmvDeviceRegsH++#ifndef MV_ASMLANGUAGE+#include "ctrlEnv/mvCtrlEnvLib.h"+/* This enumerator describes the Marvell controller possible devices that   */+/* can be connected to its device interface.                                */+typedef enum _mvDevice+{+#if defined(MV_INCLUDE_DEVICE_CS0)+	DEV_CS0 = 0,    /* Device connected to dev CS[0]    */+#endif+#if defined(MV_INCLUDE_DEVICE_CS1)+	DEV_CS1 = 1,        /* Device connected to dev CS[1]    */+#endif+#if defined(MV_INCLUDE_DEVICE_CS2)+	DEV_CS2 = 2,        /* Device connected to dev CS[2]    */+#endif+#if defined(MV_INCLUDE_DEVICE_CS3)+	DEV_CS3 = 3,        /* Device connected to dev CS[2]    */+#endif+#if defined(MV_INCLUDE_DEVICE_CS4)+	DEV_CS4 = 4,        /* Device connected to BOOT dev    */+#endif+	MV_DEV_MAX_CS = MV_DEVICE_MAX_CS+}MV_DEVICE;++ +#endif /* MV_ASMLANGUAGE */+++#define NAND_CTRL_REG		0x10470++#define NAND_ACTCEBOOT_BIT	BIT1+++#endif /* #ifndef __INCmvDeviceRegsH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c	2010-11-09 20:28:10.222495542 +0100@@ -0,0 +1,211 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.+++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+*******************************************************************************/+/*******************************************************************************+* mvOsCpuArchLib.c - Marvell CPU architecture library+*+* DESCRIPTION:+*       This library introduce Marvell API for OS dependent CPU architecture +*       APIs. This library introduce single CPU architecture services APKI +*       cross OS.+*+* DEPENDENCIES:+*       None.+*+*******************************************************************************/++/* includes */+#include <asm/processor.h>+#include "mvOs.h"++static MV_U32 read_p15_c0 (void);++/* defines  */+#define ARM_ID_REVISION_OFFS	0+#define ARM_ID_REVISION_MASK	(0xf << ARM_ID_REVISION_OFFS)++#define ARM_ID_PART_NUM_OFFS	4+#define ARM_ID_PART_NUM_MASK	(0xfff << ARM_ID_PART_NUM_OFFS)++#define ARM_ID_ARCH_OFFS	16+#define ARM_ID_ARCH_MASK	(0xf << ARM_ID_ARCH_OFFS)++#define ARM_ID_VAR_OFFS		20+#define ARM_ID_VAR_MASK		(0xf << ARM_ID_VAR_OFFS)++#define ARM_ID_ASCII_OFFS	24+#define ARM_ID_ASCII_MASK	(0xff << ARM_ID_ASCII_OFFS)++++void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,+			  MV_U32 *memHandle)+{+    void *p = kmalloc( size, GFP_KERNEL );+    *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );+    return p;+}+void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,+			    MV_U32 *memHandle)+{+    return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );+}+ +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,+			 MV_U32 memHandle)+{+    return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );+} +                                                                                                                                               +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,+		       MV_U32 memHandle )+{+    return kfree( pVirtAddr );+}+ +int mvOsRand(void)+{+    int rand;+    get_random_bytes(&rand, sizeof(rand) );+    return rand;+}++/*******************************************************************************+* mvOsCpuVerGet() - +*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit CPU Revision+*+*******************************************************************************/+MV_U32 mvOsCpuRevGet( MV_VOID )+{+	return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);+}+/*******************************************************************************+* mvOsCpuPartGet() - +*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit CPU Part number+*+*******************************************************************************/+MV_U32 mvOsCpuPartGet( MV_VOID )+{+	return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);+}+/*******************************************************************************+* mvOsCpuArchGet() - +*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit CPU Architicture number+*+*******************************************************************************/+MV_U32 mvOsCpuArchGet( MV_VOID )+{+    return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);+}+/*******************************************************************************+* mvOsCpuVarGet() - +*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit CPU Variant number+*+*******************************************************************************/+MV_U32 mvOsCpuVarGet( MV_VOID )+{+    return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);+}+/*******************************************************************************+* mvOsCpuAsciiGet() - +*+* DESCRIPTION:+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit CPU Variant number+*+*******************************************************************************/+MV_U32 mvOsCpuAsciiGet( MV_VOID )+{+    return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);+}++++/*+static unsigned long read_p15_c0 (void)+*/+/* read co-processor 15, register #0 (ID register) */+static MV_U32 read_p15_c0 (void)+{+	MV_U32 value;++	__asm__ __volatile__(+		"mrc	p15, 0, %0, c0, c0, 0   @ read control reg\n"+		: "=r" (value)+		:+		: "memory");++	return value;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h	2010-11-09 20:28:10.262495482 +0100@@ -0,0 +1,423 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.+++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+*******************************************************************************/+#ifndef _MV_OS_LNX_H_+#define _MV_OS_LNX_H_+                                                                                                                                               +                                                                                                                                               +#ifdef __KERNEL__+/* for kernel space */+#include <linux/autoconf.h>+#include <linux/interrupt.h>+#include <linux/stddef.h>+#include <linux/kernel.h>+#include <linux/init.h>+#include <linux/errno.h>+#include <linux/reboot.h>+#include <linux/pci.h>+#include <linux/kdev_t.h>+#include <linux/major.h>+#include <linux/blkdev.h>+#include <linux/console.h>+#include <linux/delay.h>+#include <linux/seq_file.h>+#include <linux/string.h>+#include <linux/slab.h>+#include <linux/kernel.h>+#include <linux/string.h>+#include <linux/slab.h>+#include <linux/mm.h>+  +#include <asm/system.h>+#include <asm/pgtable.h>+#include <asm/page.h>+#include <asm/hardirq.h>+#include <asm/dma.h>+#include <asm/io.h>+ +#include <linux/random.h>++#include "dbg-trace.h"++extern void mv_early_printk(char *fmt,...);++#define MV_ASM              __asm__ __volatile__  +#define INLINE              inline+#define MV_TRC_REC	        TRC_REC+#define mvOsPrintf          printk+#define mvOsEarlyPrintf	    mv_early_printk+#define mvOsOutput          printk+#define mvOsSPrintf         sprintf+#define mvOsMalloc(_size_)  kmalloc(_size_,GFP_ATOMIC)+#define mvOsFree            kfree+#define mvOsMemcpy          memcpy+#define mvOsSleep(_mils_)   mdelay(_mils_)+#define mvOsTaskLock()+#define mvOsTaskUnlock()+#define strtol              simple_strtoul+#define mvOsDelay(x)        mdelay(x)+#define mvOsUDelay(x)       udelay(x)+#define mvCopyFromOs        copy_from_user+#define mvCopyToOs          copy_to_user++ +#include "mvTypes.h"+#include "mvCommon.h"+  +#ifdef MV_NDEBUG+#define mvOsAssert(cond)+#else+#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }+#endif /* MV_NDEBUG */+ +#else /* __KERNEL__ */+ +/* for user space applications */+#include <stdlib.h>+#include <stdio.h>+#include <assert.h>+#include <string.h>+ +#define INLINE inline+#define mvOsPrintf printf+#define mvOsOutput printf+#define mvOsMalloc(_size_) malloc(_size_)+#define mvOsFree free+#define mvOsAssert(cond) assert(cond)+ +#endif /* __KERNEL__ */                                                                                                                                               +#define mvOsIoVirtToPhy(pDev, pVirtAddr)                            \+    pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )++#define mvOsCacheClear(pDev, p, size )                              \+    pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)+ +#define mvOsCacheFlush(pDev, p, size )                              \+    pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)+ +#define mvOsCacheInvalidate(pDev, p, size)                          \+    pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )++#define mvOsCacheUnmap(pDev, phys, size)                          \+    pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )+++#define CPU_PHY_MEM(x)              (MV_U32)x+#define CPU_MEMIO_CACHED_ADDR(x)    (void*)x+#define CPU_MEMIO_UNCACHED_ADDR(x)  (void*)x+++/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */+#define MV_MEMIO32_WRITE(addr, data)    \+    ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))++#define MV_MEMIO32_READ(addr)           \+    ((*((volatile unsigned int*)(addr))))++#define MV_MEMIO16_WRITE(addr, data)    \+    ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))++#define MV_MEMIO16_READ(addr)           \+    ((*((volatile unsigned short*)(addr))))++#define MV_MEMIO8_WRITE(addr, data)     \+    ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))++#define MV_MEMIO8_READ(addr)            \+    ((*((volatile unsigned char*)(addr))))+++/* No Fast Swap implementation (in assembler) for ARM */+#define MV_32BIT_LE_FAST(val)            MV_32BIT_LE(val)+#define MV_16BIT_LE_FAST(val)            MV_16BIT_LE(val)+#define MV_32BIT_BE_FAST(val)            MV_32BIT_BE(val)+#define MV_16BIT_BE_FAST(val)            MV_16BIT_BE(val)+    +/* 32 and 16 bit read/write in big/little endian mode */++/* 16bit write in little endian mode */+#define MV_MEMIO_LE16_WRITE(addr, data) \+        MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))++/* 16bit read in little endian mode */+static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)+{+    MV_U16 data;++    data= (MV_U16)MV_MEMIO16_READ(addr);++    return (MV_U16)MV_16BIT_LE_FAST(data);+}++/* 32bit write in little endian mode */+#define MV_MEMIO_LE32_WRITE(addr, data) \+        MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))++/* 32bit read in little endian mode */+static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)+{+    MV_U32 data;++    data= (MV_U32)MV_MEMIO32_READ(addr);++    return (MV_U32)MV_32BIT_LE_FAST(data);+}++static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)+{+    while(byteCount != 0)+    {+        *dstAddr = *srcAddr;+        dstAddr++;+        srcAddr++;+        byteCount--;+    }+}++static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)+{+    MV_U64  division = 0;++    if(divisor == 1)+	return divided;++    while(divided >= divisor)+    {+	    division++;+	    divided -= divisor;+    }+    if (modulu != NULL)+        *modulu = divided;++    return division;+}++#if defined(MV_BRIDGE_SYNC_REORDER)+extern MV_U32 *mvUncachedParam;++static __inline void mvOsBridgeReorderWA(void)+{+	volatile MV_U32 val = 0;++	val = mvUncachedParam[0];+}+#endif+++/* Flash APIs */+#define MV_FL_8_READ            MV_MEMIO8_READ+#define MV_FL_16_READ           MV_MEMIO_LE16_READ+#define MV_FL_32_READ           MV_MEMIO_LE32_READ+#define MV_FL_8_DATA_READ       MV_MEMIO8_READ+#define MV_FL_16_DATA_READ      MV_MEMIO16_READ+#define MV_FL_32_DATA_READ      MV_MEMIO32_READ+#define MV_FL_8_WRITE           MV_MEMIO8_WRITE+#define MV_FL_16_WRITE          MV_MEMIO_LE16_WRITE+#define MV_FL_32_WRITE          MV_MEMIO_LE32_WRITE+#define MV_FL_8_DATA_WRITE      MV_MEMIO8_WRITE+#define MV_FL_16_DATA_WRITE     MV_MEMIO16_WRITE+#define MV_FL_32_DATA_WRITE     MV_MEMIO32_WRITE+++/* CPU cache information */+#define CPU_I_CACHE_LINE_SIZE   32    /* 2do: replace 32 with linux core macro */+#define CPU_D_CACHE_LINE_SIZE   32    /* 2do: replace 32 with linux core macro */++#ifdef CONFIG_L2_CACHE_ENABLE+/* Data cache flush one line */+#define mvOsCacheLineFlushInv(handle, addr)                     \+{                                                               \+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\+  __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\+  __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4");		\+}++#else++/* Data cache flush one line */+#define mvOsCacheLineFlushInv(handle, addr)                     \+{                                                               \+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \+}+#endif+ +#ifdef CONFIG_L2_CACHE_ENABLE+#define mvOsCacheLineInv(handle,addr)                           \+{                                                               \+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \+ __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \+}+#else+#define mvOsCacheLineInv(handle,addr)                           \+{                                                               \+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \+}+#endif++#ifdef CONFIG_L2_CACHE_ENABLE+/* Data cache flush one line */+#define mvOsCacheLineFlush(handle, addr)                     \+{                                                               \+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\+  __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\+  __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4");          \+}++#else+/* Data cache flush one line */+#define mvOsCacheLineFlush(handle, addr)                     \+{                                                               \+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\+  __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \+}+#endif ++static __inline void mvOsPrefetch(const void *ptr)+{+#ifdef CONFIG_USE_DSP+        __asm__ __volatile__(+                "pld\t%0"+                :+                : "o" (*(char *)ptr)+                : "cc");+#else+	return;+#endif+}+++/* Flush CPU pipe */+#define CPU_PIPE_FLUSH++++++/* register manipulations  */++/******************************************************************************+* This debug function enable the write of each register that u-boot access to +* to an array in the DRAM, the function record only MV_REG_WRITE access.+* The function could not be operate when booting from flash.+* In order to print the array we use the printreg command.+******************************************************************************/+/* #define REG_DEBUG */+#if defined(REG_DEBUG)+extern int reg_arry[2048][2];+extern int reg_arry_index;+#endif++/* Marvell controller register read/write macros */+#define MV_REG_VALUE(offset)          \+                (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))++#define MV_REG_READ(offset)             \+        (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))++#if defined(REG_DEBUG)+#define MV_REG_WRITE(offset, val)    \+        MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \+        { \+                reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\+                reg_arry[reg_arry_index][1] = (val);\+                reg_arry_index++;\+        }+#else+#define MV_REG_WRITE(offset, val)    \+        MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));+#endif+                                                +#define MV_REG_BYTE_READ(offset)        \+        (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))++#if defined(REG_DEBUG)+#define MV_REG_BYTE_WRITE(offset, val)  \+        MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \+        { \+                reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\+                reg_arry[reg_arry_index][1] = (val);\+                reg_arry_index++;\+        }+#else+#define MV_REG_BYTE_WRITE(offset, val)  \+        MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))+#endif++#if defined(REG_DEBUG)+#define MV_REG_BIT_SET(offset, bitMask)                 \+        (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \+         (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \+          MV_32BIT_LE_FAST(bitMask)))); \+        { \+                reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\+                reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\+                reg_arry_index++;\+        }+#else+#define MV_REG_BIT_SET(offset, bitMask)                 \+        (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \+         (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \+          MV_32BIT_LE_FAST(bitMask))))+#endif+        +#if defined(REG_DEBUG)+#define MV_REG_BIT_RESET(offset,bitMask)                \+        (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \+         (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \+          MV_32BIT_LE_FAST(~bitMask)))); \+        { \+                reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\+                reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\+                reg_arry_index++;\+        }+#else+#define MV_REG_BIT_RESET(offset,bitMask)                \+        (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \+         (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \+          MV_32BIT_LE_FAST(~bitMask))))+#endif++++/* ARM architecture APIs */+MV_U32  mvOsCpuRevGet (MV_VOID);+MV_U32  mvOsCpuPartGet (MV_VOID);+MV_U32  mvOsCpuArchGet (MV_VOID);+MV_U32  mvOsCpuVarGet (MV_VOID);+MV_U32  mvOsCpuAsciiGet (MV_VOID);++/*  Other APIs  */+void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);+void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );+void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );+void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );+int mvOsRand(void);++#endif /* _MV_OS_LNX_H_ */++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h	2010-11-09 20:28:10.302495426 +0100@@ -0,0 +1,158 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.+++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+*******************************************************************************/+/*******************************************************************************+* mvOsLinux.h - O.S. interface header file for Linux  +*+* DESCRIPTION:+*       This header file contains OS dependent definition under Linux+*+* DEPENDENCIES:+*       Linux kernel header files.+*+* FILE REVISION NUMBER:+*       $Revision: 1.1 $+*******************************************************************************/++#ifndef __INCmvOsLinuxh+#define __INCmvOsLinuxh++/* Includes */+#include <linux/autoconf.h>+#include <linux/module.h>+#include <linux/types.h>+#include <linux/string.h>+#include <linux/kernel.h>+#include <linux/timer.h>+#include <linux/mm.h>+#include <linux/interrupt.h>+#include <linux/major.h>+#include <linux/errno.h>+#include <linux/genhd.h>+#include <linux/slab.h>+#include <linux/delay.h>+#include <linux/ide.h>+#include <linux/pci.h>++#include <asm/byteorder.h>+#include <asm/irq.h>+#include <asm/uaccess.h>+#include <asm/io.h>+#include "mvOs.h"+++/* Definitions */+#define MV_DEFAULT_QUEUE_DEPTH 2+#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION+#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN++#ifdef CONFIG_MV88F6082+ #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE+ #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2+ #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN+#endif++/* System dependent macro for flushing CPU write cache */+#if defined (MV_BRIDGE_SYNC_REORDER)+#define MV_CPU_WRITE_BUFFER_FLUSH()	do {	\+						wmb();	\+						mvOsBridgeReorderWA();	\+					} while (0)+#else+#define MV_CPU_WRITE_BUFFER_FLUSH()     wmb()+#endif /* CONFIG_MV78XX0 */++/* System dependent little endian from / to CPU conversions */+#define MV_CPU_TO_LE16(x)   cpu_to_le16(x)+#define MV_CPU_TO_LE32(x)   cpu_to_le32(x)++#define MV_LE16_TO_CPU(x)   le16_to_cpu(x)+#define MV_LE32_TO_CPU(x)   le32_to_cpu(x)++#ifdef __BIG_ENDIAN_BITFIELD+#define MV_BIG_ENDIAN_BITFIELD+#endif++/* System dependent register read / write in byte/word/dword variants */+#define MV_REG_WRITE_BYTE(base, offset, val)    writeb(val, base + offset)+#define MV_REG_WRITE_WORD(base, offset, val)    writew(val, base + offset)+#define MV_REG_WRITE_DWORD(base, offset, val)   writel(val, base + offset)+#define MV_REG_READ_BYTE(base, offset)          readb(base + offset)+#define MV_REG_READ_WORD(base, offset)          readw(base + offset)+#define MV_REG_READ_DWORD(base, offset)         readl(base + offset)+++/* Typedefs    */++/* System dependant typedefs */+typedef void            *MV_VOID_PTR;+typedef u32             *MV_U32_PTR;+typedef u16             *MV_U16_PTR;+typedef u8              *MV_U8_PTR;+typedef char            *MV_CHAR_PTR;+typedef void            *MV_BUS_ADDR_T;+typedef unsigned long   MV_CPU_FLAGS;+++/* Structures  */+/* System dependent structure */+typedef struct mvOsSemaphore+{+  int notUsed;+} MV_OS_SEMAPHORE;+++/* Functions (User implemented)*/++/* Semaphore init, take and release */+#define mvOsSemInit(x) MV_TRUE+#define mvOsSemTake(x)+#define mvOsSemRelease(x)++/* Interrupt masking and unmasking functions */+MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);+MV_VOID      mvOsRestoreFlags(MV_CPU_FLAGS);++/* Delay function in micro seconds resolution */+void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);++/* Typedefs    */+typedef enum mvBoolean+{+    MV_SFALSE, MV_STRUE+} MV_BOOLEAN;++/* System logging function */+#include "mvLog.h"+/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */+#ifdef MV_LOGGER+#define MV_SATA_SUPPORT_READ_WRITE_LONG+#endif++#define MV_IAL_LOG_ID       3++#endif /* __INCmvOsLinuxh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c	2010-11-09 20:28:10.342495568 +0100@@ -0,0 +1,376 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvCntmr.h"+#include "cpu/mvCpu.h"++/* defines  */       +#ifdef MV_DEBUG         +	#define DB(x)	x+#else                +	#define DB(x)    +#endif	             ++extern unsigned int whoAmI(void);++/*******************************************************************************+* mvCntmrLoad - +*+* DESCRIPTION:+*       Load an init Value to a given counter/timer +*+* INPUT:+*       countNum - counter number+*       value - value to be loaded+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess+*******************************************************************************/+MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)+{+	if (countNum >= MV_CNTMR_MAX_COUNTER )+	{++		mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));+		return MV_BAD_PARAM;;++	}++	MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);+	MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);++	return MV_OK;+}++/*******************************************************************************+* mvCntmrRead - +*+* DESCRIPTION:+*  	Returns the value of the given Counter/Timer     +*+* INPUT:+*       countNum - counter number+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_U32 counter value+*******************************************************************************/+MV_U32 mvCntmrRead(MV_U32 countNum)+{+	return MV_REG_READ(CNTMR_VAL_REG(countNum));+}++/*******************************************************************************+* mvCntmrWrite - +*+* DESCRIPTION:+*  	Returns the value of the given Counter/Timer     +*+* INPUT:+*       countNum - counter number+*		countVal - value to write+*+* OUTPUT:+*       None.+*+* RETURN:+*       None+*******************************************************************************/+void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)+{+	MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);+}++/*******************************************************************************+* mvCntmrCtrlSet - +*+* DESCRIPTION:+*  	Set the Control to a given counter/timer     +*+* INPUT:+*       countNum - counter number+*		pCtrl - pointer to MV_CNTMR_CTRL structure +*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess+*******************************************************************************/+MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)+{+	MV_U32 cntmrCtrl;++	if (countNum >= MV_CNTMR_MAX_COUNTER )+	{++		DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));+		return MV_BAD_PARAM;;++	}++	/* read control register */+	cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);++	+	if (pCtrl->enable)	/* enable counter\timer */+	{+		cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);+	}+	else	/* disable counter\timer */+	{+		cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);+	}++	if ( pCtrl->autoEnable ) /* Auto mode */+	{+		cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);		++	}+	else 	/* no auto mode */+	{+		cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);+	}++	MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);++	return MV_OK;++}++/*******************************************************************************+* mvCntmrCtrlGet - +*+* DESCRIPTION:+*  	Get the Control value of a given counter/timer     +*+* INPUT:+*       countNum - counter number+*		pCtrl - pointer to MV_CNTMR_CTRL structure +*+* OUTPUT:+*       Counter\Timer control value+*+* RETURN:+*       MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess+*******************************************************************************/+MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)+{+	MV_U32 cntmrCtrl;++	if (countNum >= MV_CNTMR_MAX_COUNTER )+	{+		DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));+		return MV_BAD_PARAM;;+	}++	/* read control register */+	cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);++	/* enable counter\timer */+	if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))+	{+		pCtrl->enable = MV_TRUE;+	}+	else+	{+		pCtrl->enable = MV_FALSE;+	}++	/* counter mode */+	if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))+	{+		pCtrl->autoEnable = MV_TRUE;+	}+	else+	{+		pCtrl->autoEnable = MV_FALSE;+	}++	return MV_OK;+}++/*******************************************************************************+* mvCntmrEnable - +*+* DESCRIPTION:+*  	Set the Enable-Bit to logic '1' ==> starting the counter     +*+* INPUT:+*       countNum - counter number+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess+*******************************************************************************/+MV_STATUS mvCntmrEnable(MV_U32 countNum)+{+	MV_U32 cntmrCtrl;++	if (countNum >= MV_CNTMR_MAX_COUNTER )+	{++		DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));+		return MV_BAD_PARAM;;++	}++	/* read control register */+	cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);++	/* enable counter\timer */+	cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);+++	MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);++	return MV_OK;+}++/*******************************************************************************+* mvCntmrDisable - +*+* DESCRIPTION:+*  	Stop the counter/timer running, and returns its Value     +*+* INPUT:+*       countNum - counter number+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_U32 counter\timer value+*******************************************************************************/+MV_STATUS mvCntmrDisable(MV_U32 countNum)+{+	MV_U32 cntmrCtrl;++	if (countNum >= MV_CNTMR_MAX_COUNTER )+	{++		DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));+		return MV_BAD_PARAM;;++	}++	/* read control register */+	cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);++	/* disable counter\timer */+	cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);++	MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);++	return MV_OK;+}++/*******************************************************************************+* mvCntmrStart - +*+* DESCRIPTION:+*  	Combined all the sub-operations above to one function: Load,setMode,Enable     +*+* INPUT:+*       countNum - counter number+*		value - value of the counter\timer to be set+*		pCtrl - pointer to MV_CNTMR_CTRL structure +*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess+*******************************************************************************/+MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,+                       MV_CNTMR_CTRL *pCtrl)+{++	if (countNum >= MV_CNTMR_MAX_COUNTER )+	{++		mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));+		return MV_BAD_PARAM;;++	}++	/* load value onto counter\timer */+	mvCntmrLoad(countNum,value);++	/* set the counter to load in the first time */+	mvCntmrWrite(countNum,value);++	/* set control for timer \ cunter and enable */+	mvCntmrCtrlSet(countNum,pCtrl);++	return MV_OK;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h	2010-11-09 20:28:10.381238003 +0100@@ -0,0 +1,121 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvTmrWtdgh+#define __INCmvTmrWtdgh++/* includes */+#include "mvCommon.h"+#include "mvOs.h"+#include "cntmr/mvCntmrRegs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+++/* This enumerator describe counters\watchdog numbers       */+typedef enum _mvCntmrID+{+	TIMER0 = 0,               +	TIMER1,+	WATCHDOG,+	TIMER2,               +	TIMER3,+}MV_CNTMR_ID;+++/* Counter / Timer control structure */+typedef struct _mvCntmrCtrl+{+	MV_BOOL 				enable;		/* enable */+	MV_BOOL					autoEnable;	/* counter/Timer                    */+}MV_CNTMR_CTRL;+++/* Functions */++/* Load an init Value to a given counter/timer */+MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);++/* Returns the value of the given Counter/Timer */+MV_U32 mvCntmrRead(MV_U32 countNum);++/* Write a value of the given Counter/Timer */+void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);++/* Set the Control to a given counter/timer */+MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);++/* Get the value of a given counter/timer */+MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);++/* Set the Enable-Bit to logic '1' ==> starting the counter. */+MV_STATUS mvCntmrEnable(MV_U32 countNum);++/* Stop the counter/timer running, and returns its Value. */+MV_STATUS mvCntmrDisable(MV_U32 countNum);++/* Combined all the sub-operations above to one function: Load,setMode,Enable */+MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,+                       MV_CNTMR_CTRL *pCtrl);++#endif /* __INCmvTmrWtdgh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h	2010-11-09 20:28:10.422495568 +0100@@ -0,0 +1,121 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvTmrwtdgRegsh+#define __INCmvTmrwtdgRegsh++/*******************************************/+/* ARM Timers Registers Map                */+/*******************************************/++#define CNTMR_RELOAD_REG(tmrNum)	(CNTMR_BASE + 0x10 + (tmrNum)*8 + \+						(((tmrNum) <= 3)?0:8))+#define CNTMR_VAL_REG(tmrNum)		(CNTMR_BASE + 0x14 + (tmrNum)*8 + \+						(((tmrNum) <= 3)?0:8))+#define CNTMR_CTRL_REG			(CNTMR_BASE)++/*For MV78XX0*/+#define CNTMR_CAUSE_REG		(CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))+#define CNTMR_MASK_REG		(CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))++/* ARM Timers Registers Map                */+/*******************************************/+++/* ARM Timers Control Register */+/* CPU_TIMERS_CTRL_REG (CTCR) */++#define TIMER0_NUM				0+#define TIMER1_NUM				1+#define WATCHDOG_NUM			2+#define TIMER2_NUM				3+#define TIMER3_NUM				4+	+#define CTCR_ARM_TIMER_EN_OFFS(cntr)	(cntr * 2)+#define CTCR_ARM_TIMER_EN_MASK(cntr)	(1 << CTCR_ARM_TIMER_EN_OFFS)+#define CTCR_ARM_TIMER_EN(cntr)			(1 << CTCR_ARM_TIMER_EN_OFFS(cntr))+#define CTCR_ARM_TIMER_DIS(cntr)		(0 << CTCR_ARM_TIMER_EN_OFFS(cntr))+	+#define CTCR_ARM_TIMER_AUTO_OFFS(cntr)	((cntr * 2) + 1)+#define CTCR_ARM_TIMER_AUTO_MASK(cntr)	BIT1+#define CTCR_ARM_TIMER_AUTO_EN(cntr)	(1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))+#define CTCR_ARM_TIMER_AUTO_DIS(cntr)	(0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))+++/* ARM Timer\Watchdog Reload Register */+/* CNTMR_RELOAD_REG (TRR) */++#define TRG_ARM_TIMER_REL_OFFS			0+#define TRG_ARM_TIMER_REL_MASK			0xffffffff++/* ARM Timer\Watchdog Register */+/* CNTMR_VAL_REG (TVRG) */++#define TVR_ARM_TIMER_OFFS			0+#define TVR_ARM_TIMER_MASK			0xffffffff+#define TVR_ARM_TIMER_MAX			0xffffffff++++#endif /* __INCmvTmrwtdgRegsh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c	2010-11-09 20:28:10.462495409 +0100@@ -0,0 +1,207 @@+/*+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA+ */++#include "mvOs.h"+#include "mvCpuCntrs.h"+++const static MV_CPU_CNTRS_OPS  mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =+{   +    /*0*/+    {   +        MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_DCACHE_READ_HIT,       MV_CPU_CNTRS_DCACHE_READ_MISS,+        MV_CPU_CNTRS_DCACHE_WRITE_HIT,  MV_CPU_CNTRS_DCACHE_WRITE_MISS,     MV_CPU_CNTRS_INSTRUCTIONS, +        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,+        MV_CPU_CNTRS_MMU_READ_LATENCY,  MV_CPU_CNTRS_ICACHE_READ_LATENCY,   MV_CPU_CNTRS_WB_WRITE_LATENCY,+        MV_CPU_CNTRS_LDM_STM_HOLD,      MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,+        MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS,      MV_CPU_CNTRS_INVALID,+        MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,+    },+    /*1*/+    {   +        MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_ICACHE_READ_MISS,      MV_CPU_CNTRS_DCACHE_READ_MISS,+        MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS,             MV_CPU_CNTRS_SINGLE_ISSUE,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_BRANCH_RETIRED,        MV_CPU_CNTRS_INVALID, +        MV_CPU_CNTRS_MMU_READ_BEAT,     MV_CPU_CNTRS_ICACHE_READ_LATENCY,   MV_CPU_CNTRS_WB_WRITE_BEAT,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_IS_HOLD,               MV_CPU_CNTRS_DATA_READ_ACCESS,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,+        MV_CPU_CNTRS_INVALID,+    },+    /*2*/   +    {+        MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_DCACHE_ACCESS, +        MV_CPU_CNTRS_DTLB_MISS,         MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_BRANCH_PREDICT_MISS,   MV_CPU_CNTRS_WB_WRITE_BEAT,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_DCACHE_READ_LATENCY,   MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_BIU_SIMULT_ACCESS,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID,+        MV_CPU_CNTRS_INVALID,+    },+    /*3*/   +    {+        MV_CPU_CNTRS_CYCLES,            MV_CPU_CNTRS_DCACHE_READ_MISS,      MV_CPU_CNTRS_DCACHE_WRITE_MISS,+        MV_CPU_CNTRS_TLB_MISS,          MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_INVALID, +        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_BRANCH_TAKEN,          MV_CPU_CNTRS_WB_FULL_CYCLES,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_DCACHE_READ_BEAT,      MV_CPU_CNTRS_DCACHE_WRITE_BEAT,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_BIU_ANY_ACCESS,+        MV_CPU_CNTRS_INVALID,           MV_CPU_CNTRS_INVALID,               MV_CPU_CNTRS_DATA_WRITE_ACCESS,+        MV_CPU_CNTRS_INVALID,+    }+};++MV_CPU_CNTRS_ENTRY  mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];++MV_CPU_CNTRS_EVENT*   mvCpuCntrsEventTbl[128];++void mvCpuCntrsReset(void)+{+    MV_U32 reg = 0;+   +    MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));+    MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));+}+               +void program_counter(int counter, int op)+{+    MV_U32 reg =  (1 << op) | 0x1; /*enable*/++    switch(counter)+    {+        case 0:+         __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));+         return;++        case 1:+         __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));+         return;++        case 2:+         __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));+         return;++        case 3:+         __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));+         return;++        default:+            mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);+    }+    return;+}++void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)+{+    int i;++    for(i=0; i<MV_CPU_CNTRS_NUM; i++)+    {+        pEvent->counters_sum[i] = 0;+    }+    pEvent->num_of_measurements = 0;+}++                                                                                                              +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)+{+    int                     i;+    MV_CPU_CNTRS_EVENT*     event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));++    if(event)+    {+        strncpy(event->name, name, sizeof(event->name));+        event->num_of_measurements = 0;+        event->avg_sample_count = print_threshold;+        for(i=0; i<MV_CPU_CNTRS_NUM; i++)+        {+            event->counters_before[i] = 0;+            event->counters_after[i] = 0;+            event->counters_sum[i] = 0;+        }+    }+    return event;+}++void    mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)+{+    if(event != NULL)+        mvOsFree(event);+}++                                                                                     +MV_STATUS   mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op, +                                 char* name, MV_U32 overhead)+{+    int     i;++    /* Find required operations */+    for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)+    {+        if( mvCpuCntrsOpsTbl[counter][i] == op)+        {+            strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));+            mvCpuCntrsTbl[counter].operation = op;+            mvCpuCntrsTbl[counter].opIdx = i+1;+            mvCpuCntrsTbl[counter].overhead = overhead;+            program_counter(counter, mvCpuCntrsTbl[counter].opIdx);+            mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",+                        counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);+            return MV_OK;+        }+    }+    return MV_NOT_FOUND;+}++void    mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)+{+    int     i;+    MV_U64  counters_avg;++    if(pEvent->num_of_measurements < pEvent->avg_sample_count) +        return;++    mvOsPrintf("%16s: ", pEvent->name);+    for(i=0; i<MV_CPU_CNTRS_NUM; i++)+    {+        counters_avg = mvOsDivMod64(pEvent->counters_sum[i], +                                  pEvent->num_of_measurements, NULL);+        if(counters_avg >= mvCpuCntrsTbl[i].overhead)+            counters_avg -= mvCpuCntrsTbl[i].overhead;+        else+            counters_avg = 0;++        mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);+    }+    mvOsPrintf("\n");+    mvCpuCntrsEventClear(pEvent);+    mvCpuCntrsReset();+}++void    mvCpuCntrsStatus(void)+{+    int i;++    for(i=0; i<MV_CPU_CNTRS_NUM; i++)+    {+        mvOsPrintf("#%d: %s, overhead=%d\n", +            i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);+    }+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h	2010-11-09 20:28:10.492495484 +0100@@ -0,0 +1,213 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.+++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+*******************************************************************************/+#ifndef __mvCpuCntrs_h__+#define __mvCpuCntrs_h__++#include "mvTypes.h"+#include "mvOs.h"+++#define MV_CPU_CNTRS_NUM            4+#define MV_CPU_CNTRS_OPS_NUM        32++typedef enum+{+    MV_CPU_CNTRS_INVALID = 0,+    MV_CPU_CNTRS_CYCLES,+    MV_CPU_CNTRS_ICACHE_READ_MISS,+    MV_CPU_CNTRS_DCACHE_ACCESS,+    MV_CPU_CNTRS_DCACHE_READ_MISS,+    MV_CPU_CNTRS_DCACHE_READ_HIT,+    MV_CPU_CNTRS_DCACHE_WRITE_MISS,+    MV_CPU_CNTRS_DCACHE_WRITE_HIT,+    MV_CPU_CNTRS_DTLB_MISS,+    MV_CPU_CNTRS_TLB_MISS,+    MV_CPU_CNTRS_ITLB_MISS,+    MV_CPU_CNTRS_INSTRUCTIONS,+    MV_CPU_CNTRS_SINGLE_ISSUE,+    MV_CPU_CNTRS_MMU_READ_LATENCY,+    MV_CPU_CNTRS_MMU_READ_BEAT,+    MV_CPU_CNTRS_BRANCH_RETIRED,+    MV_CPU_CNTRS_BRANCH_TAKEN,+    MV_CPU_CNTRS_BRANCH_PREDICT_MISS,+    MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,+    MV_CPU_CNTRS_WB_FULL_CYCLES,+    MV_CPU_CNTRS_WB_WRITE_LATENCY,+    MV_CPU_CNTRS_WB_WRITE_BEAT,+    MV_CPU_CNTRS_ICACHE_READ_LATENCY,+    MV_CPU_CNTRS_ICACHE_READ_BEAT,+    MV_CPU_CNTRS_DCACHE_READ_LATENCY,+    MV_CPU_CNTRS_DCACHE_READ_BEAT,+    MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,+    MV_CPU_CNTRS_DCACHE_WRITE_BEAT,+    MV_CPU_CNTRS_LDM_STM_HOLD,+    MV_CPU_CNTRS_IS_HOLD,+    MV_CPU_CNTRS_DATA_WRITE_ACCESS,+    MV_CPU_CNTRS_DATA_READ_ACCESS,+    MV_CPU_CNTRS_BIU_SIMULT_ACCESS,+    MV_CPU_CNTRS_BIU_ANY_ACCESS,++} MV_CPU_CNTRS_OPS;++typedef struct+{+    char                name[16];+    MV_CPU_CNTRS_OPS    operation;+    int                 opIdx;+    MV_U32              overhead;+    +} MV_CPU_CNTRS_ENTRY;+++typedef struct+{+    char   name[16];+    MV_U32 num_of_measurements;+    MV_U32 avg_sample_count;+    MV_U64 counters_before[MV_CPU_CNTRS_NUM];+    MV_U64 counters_after[MV_CPU_CNTRS_NUM];+    MV_U64 counters_sum[MV_CPU_CNTRS_NUM];++} MV_CPU_CNTRS_EVENT;++extern MV_CPU_CNTRS_ENTRY  mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];+++MV_STATUS           mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op, +                                      char* name, MV_U32 overhead);+void                mvCpuCntrsInit(void);+MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);+void                mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);+void                mvCpuCntrsReset(void);+void                mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);+void 		    mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);++/* internal */+void 		    program_counter(int counter, int op);++static INLINE MV_U64 mvCpuCntrsRead(const int counter)+{+    MV_U32 low = 0, high = 0;+    MV_U32 ll = 0;+    +    switch(counter)+    {+        case 0:+            MV_ASM  ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));+         break;++        case 1:+            MV_ASM  ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));+         break;++        case 2:+            MV_ASM  ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));+         break;++        case 3:+            MV_ASM  ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));+            MV_ASM  ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));+         break;++        default:+            mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);+    }+    program_counter(counter, mvCpuCntrsTbl[counter].opIdx);+    return (((MV_U64)high << 32 ) | low);++}+++static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)+{+#if 0+    int i;++    /* order is important - we want to measure the cycle count last here! */+    for(i=0; i<MV_CPU_CNTRS_NUM; i++)+        pEvent->counters_before[i] = mvCpuCntrsRead(i);+#else+    pEvent->counters_before[1] = mvCpuCntrsRead(1);+    pEvent->counters_before[3] = mvCpuCntrsRead(3);+    pEvent->counters_before[0] = mvCpuCntrsRead(0);+    pEvent->counters_before[2] = mvCpuCntrsRead(2);+#endif+}++static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)+{+    int i;++#if 0+    /* order is important - we want to measure the cycle count first here! */+    for(i=0; i<MV_CPU_CNTRS_NUM; i++)+        pEvent->counters_after[i] = mvCpuCntrsRead(i);+#else+    pEvent->counters_after[2] = mvCpuCntrsRead(2);+    pEvent->counters_after[0] = mvCpuCntrsRead(0);+    pEvent->counters_after[3] = mvCpuCntrsRead(3);+    pEvent->counters_after[1] = mvCpuCntrsRead(1);+#endif ++    for(i=0; i<MV_CPU_CNTRS_NUM; i++)+    {+        pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);	+    }+    pEvent->num_of_measurements++;+}+++#ifdef CONFIG_MV_CPU_PERF_CNTRS++#define MV_CPU_CNTRS_READ(counter)  mvCpuCntrsRead(counter)++#define MV_CPU_CNTRS_START(event)	mvCpuCntrsReadBefore(event)++#define MV_CPU_CNTRS_STOP(event)	mvCpuCntrsReadAfter(event)+			+#define MV_CPU_CNTRS_SHOW(event)	mvCpuCntrsShow(event)++#else++#define MV_CPU_CNTRS_READ(counter)+#define MV_CPU_CNTRS_START(event)+#define MV_CPU_CNTRS_STOP(event)+#define MV_CPU_CNTRS_SHOW(event)++#endif /* CONFIG_MV_CPU_PERF_CNTRS */+++#endif /* __mvCpuCntrs_h__ */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c	2010-11-09 20:28:10.522495411 +0100@@ -0,0 +1,143 @@+/*+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA+ */++#include "mvOs.h"+#include "mvCpuL2Cntrs.h"++++MV_CPU_L2_CNTRS_ENTRY   mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];++MV_CPU_L2_CNTRS_EVENT*  mvCpuL2CntrsEventTbl[128];++void mvCpuL2CntrsReset(void)+{+    MV_U32 reg = 0;+   +    MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));+    MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));+    MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));+    MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));+}+               +static void mvCpuL2CntrConfig(int counter, int op)+{+    MV_U32 reg =  (1 << op) | 0x1; /*enable*/++    switch(counter)+    {+        case 0:+         MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));+         return;++        case 1:+         MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));+         return;++        default:+            mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);+    }+    return;+}++void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)+{+    int i;++    for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)+    {+        pEvent->counters_sum[i] = 0;+    }+    pEvent->num_of_measurements = 0;+}++                                                                                                              +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)+{+    int                     i;+    MV_CPU_L2_CNTRS_EVENT*  event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));++    if(event)+    {+        strncpy(event->name, name, sizeof(event->name));+        event->num_of_measurements = 0;+        event->avg_sample_count = print_threshold;+        for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)+        {+            event->counters_before[i] = 0;+            event->counters_after[i] = 0;+            event->counters_sum[i] = 0;+        }+    }+    return event;+}++void    mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)+{+    if(event != NULL)+        mvOsFree(event);+}++                                                                                     +MV_STATUS   mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op, +                                 char* name, MV_U32 overhead)+{+    strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));+    mvCpuL2CntrsTbl[counter].operation = op;+    mvCpuL2CntrsTbl[counter].opIdx = op;+    mvCpuL2CntrsTbl[counter].overhead = overhead;+    mvCpuL2CntrConfig(counter, op);+    mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",+                        counter, op, overhead);+    return MV_OK;+}++void    mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)+{+    int     i;+    MV_U64  counters_avg;++    if(pEvent->num_of_measurements < pEvent->avg_sample_count) +        return;++    mvOsPrintf("%16s: ", pEvent->name);+    for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)+    {+        counters_avg = mvOsDivMod64(pEvent->counters_sum[i], +                                    pEvent->num_of_measurements, NULL);++        if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)+            counters_avg -= mvCpuL2CntrsTbl[i].overhead;+        else+            counters_avg = 0;++        mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);+    }+    mvOsPrintf("\n");+    mvCpuL2CntrsEventClear(pEvent);+    mvCpuL2CntrsReset();+}++void    mvCpuL2CntrsStatus(void)+{+    int i;++    for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)+    {+        mvOsPrintf("#%d: %s, overhead=%d\n", +            i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);+    }+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h	2010-11-09 20:28:10.562495466 +0100@@ -0,0 +1,151 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.+++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+*******************************************************************************/+#ifndef __mvCpuL2Cntrs_h__+#define __mvCpuL2Cntrs_h__++#include "mvTypes.h"+#include "mvOs.h"+++#define MV_CPU_L2_CNTRS_NUM         2++typedef enum+{+    MV_CPU_L2_CNTRS_ENABLE = 0,+    MV_CPU_L2_CNTRS_DATA_REQ,+    MV_CPU_L2_CNTRS_DATA_MISS_REQ,+    MV_CPU_L2_CNTRS_INST_REQ,+    MV_CPU_L2_CNTRS_INST_MISS_REQ,+    MV_CPU_L2_CNTRS_DATA_READ_REQ,+    MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,+    MV_CPU_L2_CNTRS_DATA_WRITE_REQ,+    MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,+    MV_CPU_L2_CNTRS_RESERVED,+    MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,+    MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,+    MV_CPU_L2_CNTRS_ACTIVE_CYCLES,++} MV_CPU_L2_CNTRS_OPS;++typedef struct+{+    char                name[16];+    MV_CPU_L2_CNTRS_OPS operation;+    int                 opIdx;+    MV_U32              overhead;+    +} MV_CPU_L2_CNTRS_ENTRY;+++typedef struct+{+    char   name[16];+    MV_U32 num_of_measurements;+    MV_U32 avg_sample_count;+    MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];+    MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];+    MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];++} MV_CPU_L2_CNTRS_EVENT;+++MV_STATUS               mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op, +                                        char* name, MV_U32 overhead);+void                    mvCpuL2CntrsInit(void);+MV_CPU_L2_CNTRS_EVENT*  mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);+void                    mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);+void                    mvCpuL2CntrsReset(void);+void                    mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);+void 			mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);++static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)+{+    MV_U32 low = 0, high = 0;+    +    switch(counter)+    {+        case 0:+            MV_ASM  ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));+            MV_ASM  ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));+         break;++        case 1:+            MV_ASM  ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));+            MV_ASM  ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));+         break;++        default:+            mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);+    }+    return (((MV_U64)high << 32 ) | low);++}++static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)+{+    int i;++    for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)+        pEvent->counters_before[i] = mvCpuL2CntrsRead(i);+}++static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)+{+    int i;++    for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++) +    {+        pEvent->counters_after[i] = mvCpuL2CntrsRead(i);+        pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);	+    }+    pEvent->num_of_measurements++;+}+++#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS++#define MV_CPU_L2_CNTRS_READ(counter)   mvCpuL2CntrsRead(counter)++#define MV_CPU_L2_CNTRS_START(event)	mvCpuL2CntrsReadBefore(event)++#define MV_CPU_L2_CNTRS_STOP(event)	    mvCpuL2CntrsReadAfter(event)+			+#define MV_CPU_L2_CNTRS_SHOW(event)	    mvCpuL2CntrsShow(event)++#else++#define MV_CPU_L2_CNTRS_READ(counter)+#define MV_CPU_L2_CNTRS_START(event)+#define MV_CPU_L2_CNTRS_STOP(event)+#define MV_CPU_L2_CNTRS_SHOW(event)++#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */+++#endif /* __mvCpuL2Cntrs_h__ */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c	2010-11-09 20:28:10.592495381 +0100@@ -0,0 +1,1479 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "ddr1_2/mvDram.h"+#include "boardEnv/mvBoardEnvLib.h"++#undef MV_DEBUG+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo, +                                            MV_DRAM_BANK_INFO *pBankInfo);+static MV_U32  cas2ps(MV_U8 spd_byte);+/*******************************************************************************+* mvDramBankGet - Get the DRAM bank paramters.+*+* DESCRIPTION:+*       This function retrieves DRAM bank parameters as described in +*       DRAM_BANK_INFO struct to the controller DRAM unit. In case the board +*       has its DRAM on DIMMs it will use its EEPROM to extract SPD data+*       from it. Otherwise, if the DRAM is soldered on board, the function +*       should insert its bank information into MV_DRAM_BANK_INFO struct.+*+* INPUT:+*       bankNum  - Board DRAM bank number.+*+* OUTPUT:+*       pBankInfo  - DRAM bank information struct.+*+* RETURN:+*       MV_FAIL - Bank parameters could not be read.+*+*******************************************************************************/+MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)+{+    MV_DIMM_INFO dimmInfo;++    DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum)); +    /* zero pBankInfo structure */+    memset(pBankInfo, 0, sizeof(*pBankInfo));++    if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))+    {+        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n")); +        return MV_BAD_PARAM;+    }+    if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))+    {+    DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));+    return MV_FAIL;+    }+    if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))+    {+    DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));+    return MV_FAIL;+    }++    /* convert Dimm info to Bank info */+    cpyDimm2BankInfo(&dimmInfo, pBankInfo);+    +    return MV_OK;+}++/*******************************************************************************+* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.+*+* DESCRIPTION:+*       Convert a Dimm info struct into a bank info struct.+*+* INPUT:+*       pDimmInfo - DIMM information structure.+*+* OUTPUT:+*       pBankInfo  - DRAM bank information struct.+*+* RETURN:+*       None.+*+*******************************************************************************/+static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo, +                                                MV_DRAM_BANK_INFO *pBankInfo)+{+    pBankInfo->memoryType = pDimmInfo->memoryType;        ++    /* DIMM dimensions */+    pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;+    pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;+    pBankInfo->dataWidth = pDimmInfo->dataWidth;+    pBankInfo->errorCheckType = pDimmInfo->errorCheckType;             +    pBankInfo->sdramWidth = pDimmInfo->sdramWidth;+    pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;   +    pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;+    pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;+    pBankInfo->refreshInterval = pDimmInfo->refreshInterval;+ +    /* DIMM timing parameters */+    pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;+    pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps = +                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;+    pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps = +                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;++    pBankInfo->minRowPrechargeTime     = pDimmInfo->minRowPrechargeTime;     +    pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;+    pBankInfo->minRasToCasDelay        = pDimmInfo->minRasToCasDelay;       +    pBankInfo->minRasPulseWidth        = pDimmInfo->minRasPulseWidth;       +    pBankInfo->minWriteRecoveryTime    = pDimmInfo->minWriteRecoveryTime;+    pBankInfo->minWriteToReadCmdDelay  = pDimmInfo->minWriteToReadCmdDelay;+    pBankInfo->minReadToPrechCmdDelay  = pDimmInfo->minReadToPrechCmdDelay;+    pBankInfo->minRefreshToActiveCmd   = pDimmInfo->minRefreshToActiveCmd;+               +    /* Parameters calculated from the extracted DIMM information */+    pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;+    pBankInfo->deviceDensity = pDimmInfo->deviceDensity;              +    pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /+                                 pDimmInfo->numOfModuleBanks;+ +    /* DIMM attributes (MV_TRUE for yes) */++    if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||+        (pDimmInfo->memoryType == MEM_TYPE_DDR1)   )+    {   +        if (pDimmInfo->dimmAttributes & BIT1)+            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;+        else+            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;+    }+    else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */+    {+        if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))+            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;+        else+            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;+    }++    return;+}++/*******************************************************************************+* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.+*+* DESCRIPTION:+*       Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.+*+*******************************************************************************/+MV_STATUS dimmSpdCpy(MV_VOID)+{+    MV_U32 i;+    MV_U32 spdChecksum;+     +    MV_TWSI_SLAVE twsiSlave;+    MV_U8 data[SPD_SIZE];++    /* zero dimmInfo structure */+    memset(data, 0, SPD_SIZE);++    /* read the dimm eeprom */+    DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));+    twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;+    twsiSlave.slaveAddr.type = ADDR7_BIT;+    twsiSlave.validOffset = MV_TRUE;+    twsiSlave.offset = 0;+    twsiSlave.moreThen256 = MV_FALSE;++    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,+			&twsiSlave, data, SPD_SIZE) )+    {+        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));+        return MV_FAIL;+    }+    DB(puts("DRAM: Reading dimm info succeded.\n"));+    +    /* calculate SPD checksum */+    spdChecksum = 0;+    +    for(i = 0 ; i <= 62 ; i++)+    {+        spdChecksum += data[i];+    }+    +    if ((spdChecksum & 0xff) != data[63])+    {+        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",+                            (MV_U32)(spdChecksum & 0xff), data[63]));+    }+    else+    {+        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));+    }++    /* copy the SPD content 1:1 into the DIMM 1 SPD */+    twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;+    twsiSlave.slaveAddr.type = ADDR7_BIT;+    twsiSlave.validOffset = MV_TRUE;+    twsiSlave.offset = 0;+    twsiSlave.moreThen256 = MV_FALSE;++    for(i = 0 ; i < SPD_SIZE ; i++)+    {+	twsiSlave.offset = i;+	if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,+	    			&twsiSlave, &data[i], 1) )+	{+	    mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);+	    return MV_FAIL;+	}+	mvOsDelay(5);+    }+    +    DB(puts("DRAM: Reading dimm info succeded.\n"));+    return MV_OK;+}++/*******************************************************************************+* dimmSpdGet - Get the SPD parameters.+*+* DESCRIPTION:+*       Read the DIMM SPD parameters into given struct parameter.+*+* INPUT:+*       dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.+*+* OUTPUT:+*       pDimmInfo - DIMM information structure.+*+* RETURN:+*       MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.+*+*******************************************************************************/+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)+{+    MV_U32 i;+    MV_U32 density = 1;+    MV_U32 spdChecksum;+     +    MV_TWSI_SLAVE twsiSlave;+    MV_U8 data[SPD_SIZE];++    if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))+    {+        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n")); +        return MV_BAD_PARAM;+    }++    /* zero dimmInfo structure */+    memset(data, 0, SPD_SIZE);++    /* read the dimm eeprom */+    DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));+    twsiSlave.slaveAddr.address = (dimmNum == 0) ?+                            MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;+    twsiSlave.slaveAddr.type = ADDR7_BIT;+    twsiSlave.validOffset = MV_TRUE;+    twsiSlave.offset = 0;+    twsiSlave.moreThen256 = MV_FALSE;++    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,+			&twsiSlave, data, SPD_SIZE) )+    {+        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));+        return MV_FAIL;+    }+    DB(puts("DRAM: Reading dimm info succeded.\n"));+    +    /* calculate SPD checksum */+    spdChecksum = 0;+    +        for(i = 0 ; i <= 62 ; i++)+        {+        spdChecksum += data[i];+    }+    +    if ((spdChecksum & 0xff) != data[63])+    {+        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",+                            (MV_U32)(spdChecksum & 0xff), data[63]));+    }+    else+    {+        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));+    }++    /* copy the SPD content 1:1 into the dimmInfo structure*/+    for(i = 0 ; i < SPD_SIZE ; i++)+    {+        pDimmInfo->spdRawData[i] = data[i];+        DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));+    }++    DB(mvOsPrintf("DRAM SPD Information:\n"));++    /* Memory type (DDR / SDRAM) */+    switch (data[DIMM_MEM_TYPE])+    {+        case (DIMM_MEM_TYPE_SDRAM):+            pDimmInfo->memoryType = MEM_TYPE_SDRAM;+            DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));+            break;+        case (DIMM_MEM_TYPE_DDR1):+            pDimmInfo->memoryType = MEM_TYPE_DDR1;+            DB(mvOsPrintf("DRAM Memeory type DDR1\n"));+            break;+        case (DIMM_MEM_TYPE_DDR2):+            pDimmInfo->memoryType = MEM_TYPE_DDR2;+            DB(mvOsPrintf("DRAM Memeory type DDR2\n"));+            break;+        default:+            mvOsPrintf("ERROR: Undefined memory type!\n");+            return MV_ERROR;+    }++    +    /* Number Of Row Addresses */+    pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];+    DB(mvOsPrintf("DRAM numOfRowAddr[3]         %d\n",pDimmInfo->numOfRowAddr));+        +    /* Number Of Column Addresses */+    pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];+    DB(mvOsPrintf("DRAM numOfColAddr[4]         %d\n",pDimmInfo->numOfColAddr));+        +    /* Number Of Module Banks */+    pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];+    DB(mvOsPrintf("DRAM numOfModuleBanks[5]     0x%x\n", +                                                  pDimmInfo->numOfModuleBanks));+        +    /* Number of module banks encoded differently for DDR2 */+    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)+        pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;++    /* Data Width */+    pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];+    DB(mvOsPrintf("DRAM dataWidth[6]            0x%x\n", pDimmInfo->dataWidth));+        +    /* Minimum Cycle Time At Max CasLatancy */+    pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);++    /* Error Check Type */+    pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];+    DB(mvOsPrintf("DRAM errorCheckType[11]      0x%x\n", +                                                    pDimmInfo->errorCheckType));++    /* Refresh Interval */+    pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];+    DB(mvOsPrintf("DRAM refreshInterval[12]     0x%x\n", +                                                   pDimmInfo->refreshInterval));+    +    /* Sdram Width */+    pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];+    DB(mvOsPrintf("DRAM sdramWidth[13]          0x%x\n",pDimmInfo->sdramWidth));+        +    /* Error Check Data Width */+    pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];+    DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n", +                                               pDimmInfo->errorCheckDataWidth));+    +    /* Burst Length Supported */+    /*     SDRAM/DDR1:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   |  2   |   1  * +                    *********************************************************/ +    /*     DDR2:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   | TBD  | TBD  * +                    *********************************************************/ ++    pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];+    DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n", +                                              pDimmInfo->burstLengthSupported));+    +    /* Number Of Banks On Each Device */+    pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];+    DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n", +                                            pDimmInfo->numOfBanksOnEachDevice));+    +    /* Suported Cas Latencies */+                   +    /*      SDRAM:+            *******-******-******-******-******-******-******-******* +            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +            *******-******-******-******-******-******-******-******* +    CAS =   * TBD  |  7   |  6   |  5   |  4   |  3   |   2  |   1  * +            ********************************************************/ ++    /*     DDR 1:+            *******-******-******-******-******-******-******-******* +            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +            *******-******-******-******-******-******-******-******* +    CAS =   * TBD  |  4   | 3.5  |   3  | 2.5  |  2   | 1.5  |   1  * +            *********************************************************/++    /*     DDR 2:+            *******-******-******-******-******-******-******-******* +            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +            *******-******-******-******-******-******-******-******* +    CAS =   * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * +            *********************************************************/+    +    pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];+    DB(mvOsPrintf("DRAM suportedCasLatencies[18]    0x%x\n", +                                              pDimmInfo->suportedCasLatencies));++    /* For DDR2 only, get the DIMM type information */+    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)+    {   +        pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];+        DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n", +                                                      pDimmInfo->dimmTypeInfo));+    }++    /* SDRAM Modules Attributes */+    pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];+    DB(mvOsPrintf("DRAM dimmAttributes[21]          0x%x\n",    +                                                    pDimmInfo->dimmAttributes));+    +    /* Minimum Cycle Time At Max CasLatancy Minus 1*/+    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps = +                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);++    /* Minimum Cycle Time At Max CasLatancy Minus 2*/+    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps = +                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);++    pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];+    DB(mvOsPrintf("DRAM minRowPrechargeTime[27]     0x%x\n", +                                               pDimmInfo->minRowPrechargeTime));+    pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];+    DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n", +                                           pDimmInfo->minRowActiveToRowActive));+    pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];+    DB(mvOsPrintf("DRAM minRasToCasDelay[29]        0x%x\n", +                                                  pDimmInfo->minRasToCasDelay));+    pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];+    DB(mvOsPrintf("DRAM minRasPulseWidth[30]        0x%x\n", +                                                  pDimmInfo->minRasPulseWidth));+        +    /* DIMM Bank Density */+    pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];+    DB(mvOsPrintf("DRAM dimmBankDensity[31]         0x%x\n", +                                                   pDimmInfo->dimmBankDensity));++    /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore     */+    pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];+    DB(mvOsPrintf("DRAM minWriteRecoveryTime[36]    0x%x\n", +                                              pDimmInfo->minWriteRecoveryTime));+    +    /* Only DDR2 includes Internal Write To Read Command Delay field.       */+    pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];+    DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37]  0x%x\n", +                                            pDimmInfo->minWriteToReadCmdDelay));+    +    /* Only DDR2 includes Internal Read To Precharge Command Delay field.   */+    pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];+    DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38]  0x%x\n",    +                                            pDimmInfo->minReadToPrechCmdDelay));+    +    /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */+    pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];+    DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42]   0x%x\n", +                                             pDimmInfo->minRefreshToActiveCmd));+                 +    /* calculating the sdram density. Representing device density from      */+    /* bit 20 to allow representation of 4GB and above.                     */+    /* For example, if density is 512Mbit 0x20000000, will be represent in  */+    /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example    */+    /* is density 8GB 0x200000000 >> 16 --> 0x00002000.                     */+    density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));+    pDimmInfo->deviceDensity = density * +                                pDimmInfo->numOfBanksOnEachDevice * +                                pDimmInfo->sdramWidth;+    DB(mvOsPrintf("DRAM deviceDensity           %d\n",pDimmInfo->deviceDensity));+    +    /* Number of devices includeing Error correction */+    pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) * +                                  pDimmInfo->numOfModuleBanks;+    DB(mvOsPrintf("DRAM numberOfDevices         %d\n",  +                                                   pDimmInfo->numberOfDevices));++    pDimmInfo->size = 0; ++    /* Note that pDimmInfo->size is in MB units */+    if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)+    {+        if (pDimmInfo->dimmBankDensity & BIT0)+            pDimmInfo->size += 1024;                /* Equal to 1GB     */+        else if (pDimmInfo->dimmBankDensity & BIT1)+            pDimmInfo->size += 8;                   /* Equal to 8MB     */+        else if (pDimmInfo->dimmBankDensity & BIT2)+            pDimmInfo->size += 16;                  /* Equal to 16MB    */+        else if (pDimmInfo->dimmBankDensity & BIT3)+            pDimmInfo->size += 32;                  /* Equal to 32MB    */+        else if (pDimmInfo->dimmBankDensity & BIT4)+            pDimmInfo->size += 64;                  /* Equal to 64MB    */+        else if (pDimmInfo->dimmBankDensity & BIT5)+            pDimmInfo->size += 128;                 /* Equal to 128MB   */+        else if (pDimmInfo->dimmBankDensity & BIT6) +            pDimmInfo->size += 256;                 /* Equal to 256MB   */+        else if (pDimmInfo->dimmBankDensity & BIT7) +            pDimmInfo->size += 512;                 /* Equal to 512MB   */+    }+    else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)+    {+        if (pDimmInfo->dimmBankDensity & BIT0)+            pDimmInfo->size += 1024;                /* Equal to 1GB     */+        else if (pDimmInfo->dimmBankDensity & BIT1)+            pDimmInfo->size += 2048;                /* Equal to 2GB     */+        else if (pDimmInfo->dimmBankDensity & BIT2)+            pDimmInfo->size += 16;                  /* Equal to 16MB    */+        else if (pDimmInfo->dimmBankDensity & BIT3)+            pDimmInfo->size += 32;                  /* Equal to 32MB    */+        else if (pDimmInfo->dimmBankDensity & BIT4)+            pDimmInfo->size += 64;                  /* Equal to 64MB    */+        else if (pDimmInfo->dimmBankDensity & BIT5)+            pDimmInfo->size += 128;                 /* Equal to 128MB   */+        else if (pDimmInfo->dimmBankDensity & BIT6) +            pDimmInfo->size += 256;                 /* Equal to 256MB   */+        else if (pDimmInfo->dimmBankDensity & BIT7) +            pDimmInfo->size += 512;                 /* Equal to 512MB   */+    }+    else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */+    {+        if (pDimmInfo->dimmBankDensity & BIT0)+            pDimmInfo->size += 1024;                /* Equal to 1GB     */+        else if (pDimmInfo->dimmBankDensity & BIT1)+            pDimmInfo->size += 2048;                /* Equal to 2GB     */+        else if (pDimmInfo->dimmBankDensity & BIT2)+            pDimmInfo->size += 4096;                /* Equal to 4GB     */+        else if (pDimmInfo->dimmBankDensity & BIT3)+            pDimmInfo->size += 8192;                /* Equal to 8GB     */+        else if (pDimmInfo->dimmBankDensity & BIT4)+            pDimmInfo->size += 16384;               /* Equal to 16GB    */+        else if (pDimmInfo->dimmBankDensity & BIT5)+            pDimmInfo->size += 128;                 /* Equal to 128MB   */+        else if (pDimmInfo->dimmBankDensity & BIT6) +            pDimmInfo->size += 256;                 /* Equal to 256MB   */+        else if (pDimmInfo->dimmBankDensity & BIT7) +            pDimmInfo->size += 512;                 /* Equal to 512MB   */+    }+    +    pDimmInfo->size *= pDimmInfo->numOfModuleBanks;++    DB(mvOsPrintf("Dram: dimm size    %dMB \n",pDimmInfo->size));++    return MV_OK;+}++/*******************************************************************************+* dimmSpdPrint - Print the SPD parameters.+*+* DESCRIPTION:+*       Print the Dimm SPD parameters.+*+* INPUT:+*       pDimmInfo - DIMM information structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID dimmSpdPrint(MV_U32 dimmNum)+{+    MV_DIMM_INFO dimmInfo;+    MV_U32  i, temp = 0;+    MV_U32  k, maskLeftOfPoint = 0, maskRightOfPoint = 0;+    MV_U32  rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;+    MV_U32  busClkPs;+    MV_U8   trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,+            temp_buf[40], *spdRawData;++    busClkPs = 1000000000 / (mvBoardSysClkGet() / 100);  /* in 10 ps units */++    spdRawData = dimmInfo.spdRawData;+    +    if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))+    {+        mvOsOutput("ERROR: Could not read SPD information!\n");+        return;+    }++    /* find Manufactura of Dimm Module */+    mvOsOutput("\nManufacturer's JEDEC ID Code:   ");+    for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)+    {+        mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);+    }+    mvOsOutput("\n");++    /* Manufacturer's Specific Data */+    for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)+    {+        temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];+    }+    mvOsOutput("Manufacturer's Specific Data:   %s\n", temp_buf);++    /* Module Part Number */+    for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)+    {+        temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];+    }+    mvOsOutput("Module Part Number:             %s\n", temp_buf);++    /* Module Serial Number */+    for(i = 0; i < sizeof(MV_U32); i++)+    {+    	temp |= spdRawData[95+i] << 8*i;+    }+    mvOsOutput("DIMM Serial No.                 %ld (%lx)\n", (long)temp, +                                    (long)temp);++    /* find Manufac-Data of Dimm Module */+    mvOsOutput("Manufactoring Date:             Year 20%d%d/ ww %d%d\n", +                        ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf), +                        ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf)); +    /* find modul_revision of Dimm Module */+    mvOsOutput("Module Revision:                %d.%d\n", +                                                spdRawData[91], spdRawData[92]); ++    /* find manufac_place of Dimm Module */+    mvOsOutput("manufac_place:                  %d\n", spdRawData[72]);+    +    /* go over the first 35 I2C data bytes */+    for(i = 2 ; i <= 35 ; i++)+       switch(i)+        {+            case 2:  /* Memory type (DDR1/2 / SDRAM) */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                    mvOsOutput("Dram Type is:                   SDRAM\n");+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                    mvOsOutput("Dram Type is:                   SDRAM DDR1\n");+                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                    mvOsOutput("Dram Type is:                   SDRAM DDR2\n");+                else+                    mvOsOutput("Dram Type unknown\n");+                break;+/*----------------------------------------------------------------------------*/++            case 3:  /* Number Of Row Addresses */+                mvOsOutput("Module Number of row addresses: %d\n", +                                                        dimmInfo.numOfRowAddr);+                break;+/*----------------------------------------------------------------------------*/+    +            case 4:  /* Number Of Column Addresses */+                mvOsOutput("Module Number of col addresses: %d\n", +                                                        dimmInfo.numOfColAddr);+                break;+/*----------------------------------------------------------------------------*/+    +            case 5:  /* Number Of Module Banks */+                mvOsOutput("Number of Banks on Mod.:        %d\n",  +                                                    dimmInfo.numOfModuleBanks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 6:  /* Data Width */+                mvOsOutput("Module Data Width:              %d bit\n",  +                                                           dimmInfo.dataWidth);+                break;+/*----------------------------------------------------------------------------*/+    +            case 8:  /* Voltage Interface */+                switch(spdRawData[i])+                {+                    case 0x0:+                        mvOsOutput("Module is               TTL_5V_TOLERANT\n");+                        break;+                    case 0x1:+                        mvOsOutput("Module is               LVTTL\n");+                        break;+                    case 0x2:+                        mvOsOutput("Module is               HSTL_1_5V\n");+                        break;+                    case 0x3:+                        mvOsOutput("Module is               SSTL_3_3V\n");+                        break;+                    case 0x4:+                        mvOsOutput("Module is               SSTL_2_5V\n");+                        break;+                    case 0x5:+                        if (dimmInfo.memoryType != MEM_TYPE_SDRAM)+                        {+                            mvOsOutput("Module is                 SSTL_1_8V\n");+                            break;+                        }+                    default:+                        mvOsOutput("Module is               VOLTAGE_UNKNOWN\n");+                        break;+                }+                break;+/*----------------------------------------------------------------------------*/+    +            case 9:  /* Minimum Cycle Time At Max CasLatancy */+                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;+                rightOfPoint = (spdRawData[i] & 0x0f) * 10;+                +                /* DDR2 addition of right of point */+                if ((spdRawData[i] & 0x0f) == 0xA)+                {+                    rightOfPoint = 25;+                }+                if ((spdRawData[i] & 0x0f) == 0xB)+                {+                    rightOfPoint = 33;+                }+                if ((spdRawData[i] & 0x0f) == 0xC)+                {+                    rightOfPoint = 66;+                }+                if ((spdRawData[i] & 0x0f) == 0xD)+                {+                    rightOfPoint = 75;+                }+                mvOsOutput("Minimum Cycle Time At Max CL:   %d.%d [ns]\n",+                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 10: /* Clock To Data Out */+                div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;+                time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                leftOfPoint     = time_tmp / div;+                rightOfPoint    = time_tmp % div;+                mvOsOutput("Clock To Data Out:              %d.%d [ns]\n",+                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 11: /* Error Check Type */+                mvOsOutput("Error Check Type (0=NONE):      %d\n", +                                                      dimmInfo.errorCheckType);+                break;+/*----------------------------------------------------------------------------*/++            case 12: /* Refresh Interval */+                mvOsOutput("Refresh Rate:                   %x\n", +                                                     dimmInfo.refreshInterval);+                break;+/*----------------------------------------------------------------------------*/+    +            case 13: /* Sdram Width */+                mvOsOutput("Sdram Width:                    %d bits\n",     +                                                          dimmInfo.sdramWidth);+                break;+/*----------------------------------------------------------------------------*/+    +            case 14: /* Error Check Data Width */+                mvOsOutput("Error Check Data Width:         %d bits\n", +                                                 dimmInfo.errorCheckDataWidth);+                break;+/*----------------------------------------------------------------------------*/++           case 15: /* Minimum Clock Delay is unsupported */+                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||+                    (dimmInfo.memoryType == MEM_TYPE_DDR1))+                {+                    mvOsOutput("Minimum Clk Delay back to back: %d\n", +                                                                spdRawData[i]);+                }+                break;+/*----------------------------------------------------------------------------*/+    +            case 16: /* Burst Length Supported */+    /*     SDRAM/DDR1:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   |  2   |   1  * +                    *********************************************************/ +    /*     DDR2:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   | TBD  | TBD  * +                    *********************************************************/ +                mvOsOutput("Burst Length Supported: ");+                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||+                    (dimmInfo.memoryType == MEM_TYPE_DDR1))+                {+                    if (dimmInfo.burstLengthSupported & BIT0)+                        mvOsOutput("1, ");+                    if (dimmInfo.burstLengthSupported & BIT1)+                        mvOsOutput("2, ");+                }+                if (dimmInfo.burstLengthSupported & BIT2)+                    mvOsOutput("4, ");+                if (dimmInfo.burstLengthSupported & BIT3) +                    mvOsOutput("8, ");+                +                mvOsOutput(" Bit \n");+                break;+/*----------------------------------------------------------------------------*/+    +            case 17: /* Number Of Banks On Each Device */+                mvOsOutput("Number Of Banks On Each Chip:   %d\n",  +                                              dimmInfo.numOfBanksOnEachDevice);+                break;+/*----------------------------------------------------------------------------*/+    +            case 18: /* Suported Cas Latencies */+                   +            /*      SDRAM:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +            CAS =   * TBD  |  7   |  6   |  5   |  4   |  3   |   2  |   1  * +                    ********************************************************/ ++            /*     DDR 1:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +            CAS =   * TBD  |  4   | 3.5  |   3  | 2.5  |  2   | 1.5  |   1  * +                    *********************************************************/++            /*     DDR 2:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +            CAS =   * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * +                    *********************************************************/++                mvOsOutput("Suported Cas Latencies: (CL) 			");+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    for (k = 0; k <=7; k++)+                    {+                        if (dimmInfo.suportedCasLatencies & (1 << k))+                            mvOsOutput("%d,             ", k+1);+                    }+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if (dimmInfo.suportedCasLatencies & BIT0)+                        mvOsOutput("1, ");+                    if (dimmInfo.suportedCasLatencies & BIT1)+                        mvOsOutput("1.5, ");+                    if (dimmInfo.suportedCasLatencies & BIT2)+                        mvOsOutput("2, ");+                    if (dimmInfo.suportedCasLatencies & BIT3)+                        mvOsOutput("2.5, ");+                    if (dimmInfo.suportedCasLatencies & BIT4)+                        mvOsOutput("3, ");+                    if (dimmInfo.suportedCasLatencies & BIT5)+                        mvOsOutput("3.5, ");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                {+                    if (dimmInfo.suportedCasLatencies & BIT2)+                        mvOsOutput("2, ");+                    if (dimmInfo.suportedCasLatencies & BIT3)+                        mvOsOutput("3, ");+                    if (dimmInfo.suportedCasLatencies & BIT4)+                        mvOsOutput("4, ");+                    if (dimmInfo.suportedCasLatencies & BIT5)+                        mvOsOutput("5, ");		+                }+                else+                    mvOsOutput("?.?, ");		+                mvOsOutput("\n");+                break;+/*----------------------------------------------------------------------------*/+    +            case 20:   /* DDR2 DIMM type info */+                if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                {+                    if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))+                        mvOsOutput("Registered DIMM (RDIMM)\n");+                    else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))+                        mvOsOutput("Unbuffered DIMM (UDIMM)\n");+                    else +                        mvOsOutput("Unknown DIMM type.\n");+                }++                break;+/*----------------------------------------------------------------------------*/+   +            case 21: /* SDRAM Modules Attributes */+                mvOsOutput("\nModule Attributes (SPD Byte 21): \n");+                +                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    if (dimmInfo.dimmAttributes & BIT0)+                        mvOsOutput(" Buffered Addr/Control Input:   Yes\n");+                    else+                        mvOsOutput(" Buffered Addr/Control Input:   No\n");++                    if (dimmInfo.dimmAttributes & BIT1)+                        mvOsOutput(" Registered Addr/Control Input: Yes\n");+                    else+                        mvOsOutput(" Registered Addr/Control Input: No\n");+   +                    if (dimmInfo.dimmAttributes & BIT2)+                        mvOsOutput(" On-Card PLL (clock):           Yes \n");+                    else+                        mvOsOutput(" On-Card PLL (clock):           No \n");++                    if (dimmInfo.dimmAttributes & BIT3)+                        mvOsOutput(" Bufferd DQMB Input:            Yes \n");+                    else+                        mvOsOutput(" Bufferd DQMB Inputs:           No \n");+   +                    if (dimmInfo.dimmAttributes & BIT4)+                        mvOsOutput(" Registered DQMB Inputs:        Yes \n");+                    else+                        mvOsOutput(" Registered DQMB Inputs:        No \n");+ +                    if (dimmInfo.dimmAttributes & BIT5)+                        mvOsOutput(" Differential Clock Input:      Yes \n");+                    else+                        mvOsOutput(" Differential Clock Input:      No \n");+   +                    if (dimmInfo.dimmAttributes & BIT6)+                        mvOsOutput(" redundant Row Addressing:      Yes \n");+                    else+                        mvOsOutput(" redundant Row Addressing:      No \n");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if (dimmInfo.dimmAttributes & BIT0)+                        mvOsOutput(" Buffered Addr/Control Input:   Yes\n");+                    else +                        mvOsOutput(" Buffered Addr/Control Input:   No\n");+   +                    if (dimmInfo.dimmAttributes & BIT1)+                        mvOsOutput(" Registered Addr/Control Input: Yes\n");+                    else+                        mvOsOutput(" Registered Addr/Control Input: No\n");+   +                    if (dimmInfo.dimmAttributes & BIT2)+                        mvOsOutput(" On-Card PLL (clock):           Yes \n");+                    else+                        mvOsOutput(" On-Card PLL (clock):           No \n");+            +                    if (dimmInfo.dimmAttributes & BIT3)+                        mvOsOutput(" FET Switch On-Card Enabled:    Yes \n");+                    else+                        mvOsOutput(" FET Switch On-Card Enabled:    No \n");+                    +                    if (dimmInfo.dimmAttributes & BIT4)+                        mvOsOutput(" FET Switch External Enabled:   Yes \n");+                    else+                        mvOsOutput(" FET Switch External Enabled:   No \n");++                    if (dimmInfo.dimmAttributes & BIT5)+                        mvOsOutput(" Differential Clock Input:      Yes \n");+                    else+                        mvOsOutput(" Differential Clock Input:      No \n");+                }+                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */+                {+                    mvOsOutput(" Number of Active Registers on the DIMM: %d\n", +                                        (dimmInfo.dimmAttributes & 0x3) + 1);+            +                    mvOsOutput(" Number of PLLs on the DIMM: %d\n", +                                      ((dimmInfo.dimmAttributes) >> 2) & 0x3);+               +                    if (dimmInfo.dimmAttributes & BIT4)+                        mvOsOutput(" FET Switch External Enabled:   Yes \n");+                    else+                        mvOsOutput(" FET Switch External Enabled:   No \n");++                    if (dimmInfo.dimmAttributes & BIT6)+                        mvOsOutput(" Analysis probe installed:      Yes \n");+                    else+                        mvOsOutput(" Analysis probe installed:      No \n");+                }+                +                break;+/*----------------------------------------------------------------------------*/++            case 22: /* Suported AutoPreCharge */+                mvOsOutput("\nModul Attributes (SPD Byte 22): \n");+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    if ( spdRawData[i] & BIT0 )+                        mvOsOutput(" Early Ras Precharge:           Yes \n");+                    else+                        mvOsOutput(" Early Ras Precharge:           No \n");+                                                        +                    if ( spdRawData[i] & BIT1 )                 +                        mvOsOutput(" AutoPreCharge:                 Yes \n");+                    else+                        mvOsOutput(" AutoPreCharge:                 No \n");+                                                            +                    if ( spdRawData[i] & BIT2 )                 +                        mvOsOutput(" Precharge All:                 Yes \n");+                    else+                        mvOsOutput(" Precharge All:                 No \n");+                                                        +                    if ( spdRawData[i] & BIT3 )                 +                        mvOsOutput(" Write 1/ReadBurst:             Yes \n");+                    else+                        mvOsOutput(" Write 1/ReadBurst:             No \n");+                                                        +                    if ( spdRawData[i] & BIT4 )                 +                        mvOsOutput(" lower VCC tolerance:           5%%\n");+                    else+                        mvOsOutput(" lower VCC tolerance:           10%%\n");+                                                        +                    if ( spdRawData[i] & BIT5 )                 +                        mvOsOutput(" upper VCC tolerance:           5%%\n");+                    else+                        mvOsOutput(" upper VCC tolerance:           10%%\n");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if ( spdRawData[i] & BIT0 )+                        mvOsOutput(" Supports Weak Driver:          Yes \n");+                    else+                        mvOsOutput(" Supports Weak Driver:          No \n");++                    if ( !(spdRawData[i] & BIT4) )+                        mvOsOutput(" lower VCC tolerance:           0.2V\n");+   +                    if ( !(spdRawData[i] & BIT5) )+                        mvOsOutput(" upper VCC tolerance:           0.2V\n");++                    if ( spdRawData[i] & BIT6 )+                        mvOsOutput(" Concurrent Auto Preharge:      Yes \n");+                    else+                        mvOsOutput(" Concurrent Auto Preharge:      No \n");++                    if ( spdRawData[i] & BIT7 )+                        mvOsOutput(" Supports Fast AP:              Yes \n");+                    else+                        mvOsOutput(" Supports Fast AP:              No \n");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                {+                    if ( spdRawData[i] & BIT0 )+                        mvOsOutput(" Supports Weak Driver:          Yes \n");+                    else+                        mvOsOutput(" Supports Weak Driver:          No \n");+                }+                break;+/*----------------------------------------------------------------------------*/+    +            case 23:+            /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */+                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;+                rightOfPoint = (spdRawData[i] & 0x0f) * 10;+                +                /* DDR2 addition of right of point */+                if ((spdRawData[i] & 0x0f) == 0xA)+                {+                    rightOfPoint = 25;+                }+                if ((spdRawData[i] & 0x0f) == 0xB)+                {+                    rightOfPoint = 33;+                }+                if ((spdRawData[i] & 0x0f) == 0xC)+                {+                    rightOfPoint = 66;+                }+                if ((spdRawData[i] & 0x0f) == 0xD)+                {+                    rightOfPoint = 75;+                }++                mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"+                           "(0 = Not supported): %d.%d [ns]\n",+                           leftOfPoint, rightOfPoint );+                break;+/*----------------------------------------------------------------------------*/+    +            case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/+                div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;+                time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                    ((spdRawData[i] & 0x0f));+                leftOfPoint     = time_tmp / div;+                rightOfPoint    = time_tmp % div;+                mvOsOutput("Clock To Data Out (2nd CL value): 		%d.%d [ns]\n",+                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 25: +            /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;+                    rightOfPoint = (spdRawData[i] & 0x3) * 25;+                }+                else    /* DDR1 or DDR2 */ +                {+                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;+                    rightOfPoint = (spdRawData[i] & 0x0f) * 10;+                    +                    /* DDR2 addition of right of point */+                    if ((spdRawData[i] & 0x0f) == 0xA)+                    {+                        rightOfPoint = 25;+                    }+                    if ((spdRawData[i] & 0x0f) == 0xB)+                    {+                        rightOfPoint = 33;+                    }+                    if ((spdRawData[i] & 0x0f) == 0xC)+                    {+                        rightOfPoint = 66;+                    }+                    if ((spdRawData[i] & 0x0f) == 0xD)+                    {+                        rightOfPoint = 75;+                    }+                }+                mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy" +                           "(0 = Not supported): %d.%d [ns]\n",+                           leftOfPoint, rightOfPoint );+                break;+/*----------------------------------------------------------------------------*/+    +            case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;+                    rightOfPoint = (spdRawData[i] & 0x3) * 25;+                }+                else    /* DDR1 or DDR2 */ +                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint     = 0;+                    rightOfPoint    = time_tmp;+                }+                mvOsOutput("Clock To Data Out (3rd CL value): 		%d.%2d[ns]\n",+                                                  leftOfPoint, rightOfPoint );+                break;+/*----------------------------------------------------------------------------*/+    +            case 27: /* Minimum Row Precharge Time */+                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;+                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0xff : 0xfc;+                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0x00 : 0x03;+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;+                temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/+                trp_clocks = (temp + (busClkPs-1)) /  busClkPs;    +                mvOsOutput("Minimum Row Precharge Time [ns]: 		%d.%d = " +                           "in Clk cycles %d\n", +                           leftOfPoint, rightOfPoint, trp_clocks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 28: /* Minimum Row Active to Row Active Time */+                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;+                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0xff : 0xfc;+                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0x00 : 0x03;+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;+                temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/+                trrd_clocks = (temp + (busClkPs-1)) / busClkPs;+                mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: " +                           "%d.%d = in Clk cycles %d\n",+                            leftOfPoint, rightOfPoint, trp_clocks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 29: /* Minimum Ras-To-Cas Delay */+                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;+                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0xff : 0xfc;+                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0x00 : 0x03;+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;  +                temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/+                trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;+                mvOsOutput("Minimum Ras-To-Cas Delay [ns]: 			%d.%d = "+                           "in Clk cycles %d\n", +                           leftOfPoint, rightOfPoint, trp_clocks);+                break;+/*----------------------------------------------------------------------------*/+   +            case 30: /* Minimum Ras Pulse Width */+                tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;+                mvOsOutput("Minimum Ras Pulse Width [ns]: 			%d = "+                           "in Clk cycles %d\n", spdRawData[i], tras_clocks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 31: /* Module Bank Density */+                mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");++                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    if (dimmInfo.dimmBankDensity & BIT0)+                        mvOsOutput("1GB, ");+                    if (dimmInfo.dimmBankDensity & BIT1)+                        mvOsOutput("8MB, ");+                    if (dimmInfo.dimmBankDensity & BIT2)+                        mvOsOutput("16MB, ");+                    if (dimmInfo.dimmBankDensity & BIT3)+                        mvOsOutput("32MB, ");+                    if (dimmInfo.dimmBankDensity & BIT4)+                        mvOsOutput("64MB, ");+                    if (dimmInfo.dimmBankDensity & BIT5)+                        mvOsOutput("128MB, ");+                    if (dimmInfo.dimmBankDensity & BIT6) +                        mvOsOutput("256MB, ");+                    if (dimmInfo.dimmBankDensity & BIT7) +                        mvOsOutput("512MB, ");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if (dimmInfo.dimmBankDensity & BIT0)+                        mvOsOutput("1GB, ");+                    if (dimmInfo.dimmBankDensity & BIT1)+                        mvOsOutput("2GB, ");+                    if (dimmInfo.dimmBankDensity & BIT2)+                        mvOsOutput("16MB, ");+                    if (dimmInfo.dimmBankDensity & BIT3)+                        mvOsOutput("32MB, ");+                    if (dimmInfo.dimmBankDensity & BIT4)+                        mvOsOutput("64MB, ");+                    if (dimmInfo.dimmBankDensity & BIT5)+                        mvOsOutput("128MB, ");+                    if (dimmInfo.dimmBankDensity & BIT6) +                        mvOsOutput("256MB, ");+                    if (dimmInfo.dimmBankDensity & BIT7) +                        mvOsOutput("512MB, ");+                }+                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */+                {+                    if (dimmInfo.dimmBankDensity & BIT0)+                        mvOsOutput("1GB, ");+                    if (dimmInfo.dimmBankDensity & BIT1)+                        mvOsOutput("2GB, ");+                    if (dimmInfo.dimmBankDensity & BIT2)+                        mvOsOutput("4GB, ");+                    if (dimmInfo.dimmBankDensity & BIT3)+                        mvOsOutput("8GB, ");+                    if (dimmInfo.dimmBankDensity & BIT4)+                        mvOsOutput("16GB, ");+                    if (dimmInfo.dimmBankDensity & BIT5)+                    mvOsOutput("128MB, ");+                        if (dimmInfo.dimmBankDensity & BIT6) +                    mvOsOutput("256MB, ");+                        if (dimmInfo.dimmBankDensity & BIT7) +                    mvOsOutput("512MB, ");+                }+                mvOsOutput("\n");+                break;+/*----------------------------------------------------------------------------*/+    +            case 32: /* Address And Command Setup Time (measured in ns/1000) */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                    leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100; +                }+                mvOsOutput("Address And Command Setup Time [ns]: 		%d.%d\n",+                                                     leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 33: /* Address And Command Hold Time */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                    leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100;                 +                }+                mvOsOutput("Address And Command Hold Time [ns]: 		%d.%d\n",+                                                   leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 34: /* Data Input Setup Time */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                        leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100;                 +                }+                mvOsOutput("Data Input Setup Time [ns]: 			%d.%d\n", +                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 35: /* Data Input Hold Time */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                        leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100;                 +                }+                mvOsOutput("Data Input Hold Time [ns]: 			%d.%d\n\n", +                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 36: /* Relevant for DDR2 only: Write Recovery Time */+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;  +                mvOsOutput("Write Recovery Time [ns]: 			%d.%d\n", +                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+        }+    +}+++/*+ * translate ns.ns/10 coding of SPD timing values+ * into ps unit values+ */+/*******************************************************************************+*  cas2ps - Translate x.y ns parameter to pico-seconds values+*+* DESCRIPTION:+*       This function translates x.y nano seconds to its value in pico seconds.+*       For example 3.75ns will return 3750.+*+* INPUT:+*       spd_byte - DIMM SPD byte.+*+* OUTPUT:+*       None.+*+* RETURN:+*       value in pico seconds.+*+*******************************************************************************/+static MV_U32  cas2ps(MV_U8 spd_byte)+{+    MV_U32 ns, ns10;+    +    /* isolate upper nibble */+    ns = (spd_byte >> 4) & 0x0F;+    /* isolate lower nibble */+    ns10 = (spd_byte & 0x0F);+    +    if( ns10 < 10 ) {+        ns10 *= 10;+    }+    else if( ns10 == 10 )+        ns10 = 25;+    else if( ns10 == 11 )+        ns10 = 33;+    else if( ns10 == 12 )+        ns10 = 66;+    else if( ns10 == 13 )+        ns10 = 75;+    else +    {+        mvOsOutput("cas2ps Err. unsupported cycle time.\n");+    }+    +    return (ns*1000 + ns10*10);+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h	2010-11-09 20:28:10.622495522 +0100@@ -0,0 +1,191 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDram+#define __INCmvDram++#include "ddr1_2/mvDramIf.h"+#include "twsi/mvTwsi.h"++#define MAX_DIMM_NUM 			2+#define SPD_SIZE			128++/* Dimm spd offsets */+#define DIMM_MEM_TYPE 						2+#define DIMM_ROW_NUM 						3+#define DIMM_COL_NUM 						4+#define DIMM_MODULE_BANK_NUM 				5+#define DIMM_DATA_WIDTH 					6+#define DIMM_VOLT_IF 						8+#define DIMM_MIN_CC_AT_MAX_CAS 				9+#define DIMM_ERR_CHECK_TYPE 				11+#define DIMM_REFRESH_INTERVAL 				12+#define DIMM_SDRAM_WIDTH 					13+#define DIMM_ERR_CHECK_DATA_WIDTH 			14+#define DIMM_MIN_CLK_DEL 					15+#define DIMM_BURST_LEN_SUP 					16+#define DIMM_DEV_BANK_NUM 					17+#define DIMM_SUP_CAL 						18+#define DIMM_DDR2_TYPE_INFORMATION          20      /* DDR2 only */+#define DIMM_BUF_ADDR_CONT_IN 				21+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1		23+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2		25+#define DIMM_MIN_ROW_PRECHARGE_TIME			27+#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE	28+#define DIMM_MIN_RAS_TO_CAS_DELAY			29+#define DIMM_MIN_RAS_PULSE_WIDTH			30+#define DIMM_BANK_DENSITY					31+#define DIMM_MIN_WRITE_RECOVERY_TIME        36+#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY    37+#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY    38+#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD    42++/* Dimm Memory Type values */+#define DIMM_MEM_TYPE_SDRAM					0x4+#define DIMM_MEM_TYPE_DDR1 					0x7+#define DIMM_MEM_TYPE_DDR2 					0x8+        +#define DIMM_MODULE_MANU_OFFS 		64+#define DIMM_MODULE_MANU_SIZE 		8+#define DIMM_MODULE_VEN_OFFS 		73 +#define DIMM_MODULE_VEN_SIZE 		25+#define DIMM_MODULE_ID_OFFS 		99+#define DIMM_MODULE_ID_SIZE 		18++/* enumeration for voltage levels. */+typedef enum _mvDimmVoltageIf+{+    TTL_5V_TOLERANT, +    LVTTL, +    HSTL_1_5V, +    SSTL_3_3V, +    SSTL_2_5V, +    VOLTAGE_UNKNOWN, +} MV_DIMM_VOLTAGE_IF;+++/* enumaration for SDRAM CAS Latencies. */+typedef enum _mvDimmSdramCas+{+    SD_CL_1 =1,  +    SD_CL_2,  +    SD_CL_3, +    SD_CL_4, +    SD_CL_5, +    SD_CL_6, +    SD_CL_7, +    SD_FAULT+}MV_DIMM_SDRAM_CAS;+++/* DIMM information structure */                                                    +typedef struct _mvDimmInfo+{+    MV_MEMORY_TYPE  memoryType; 	/* DDR or SDRAM */++    MV_U8       spdRawData[SPD_SIZE];  	/* Content of SPD-EEPROM copied 1:1  */++    /* DIMM dimensions */+    MV_U32  numOfRowAddr;+    MV_U32  numOfColAddr;+    MV_U32  numOfModuleBanks;+    MV_U32  dataWidth;+    MV_U32  errorCheckType;             /* ECC , PARITY..*/+    MV_U32  sdramWidth;                 /* 4,8,16 or 32 */+    MV_U32  errorCheckDataWidth;        /* 0 - no, 1 - Yes */+    MV_U32  burstLengthSupported;+    MV_U32  numOfBanksOnEachDevice;+    MV_U32  suportedCasLatencies;+    MV_U32  refreshInterval;+    MV_U32  dimmBankDensity;+    MV_U32  dimmTypeInfo;           /* DDR2 only */+    MV_U32  dimmAttributes;++    /* DIMM timing parameters */+    MV_U32  minCycleTimeAtMaxCasLatPs;	+    MV_U32  minCycleTimeAtMaxCasLatMinus1Ps;+    MV_U32  minCycleTimeAtMaxCasLatMinus2Ps;+	MV_U32  minRowPrechargeTime;+	MV_U32  minRowActiveToRowActive;+	MV_U32  minRasToCasDelay;+	MV_U32  minRasPulseWidth;+    MV_U32  minWriteRecoveryTime;   /* DDR2 only */+    MV_U32  minWriteToReadCmdDelay; /* DDR2 only */+    MV_U32  minReadToPrechCmdDelay; /* DDR2 only */+    MV_U32  minRefreshToActiveCmd;  /* DDR2 only */++    /* Parameters calculated from the extracted DIMM information */+    MV_U32  size;               /* 16,64,128,256 or 512 MByte in MB units */+    MV_U32  deviceDensity;      /* 16,64,128,256 or 512 Mbit in MB units  */+    MV_U32  numberOfDevices;++} MV_DIMM_INFO;+++MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);+MV_VOID dimmSpdPrint(MV_U32 dimmNum);+MV_STATUS dimmSpdCpy(MV_VOID);++#endif /* __INCmvDram */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c	2010-11-09 20:28:10.662495471 +0100@@ -0,0 +1,1599 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++/* includes */+#include "ddr1_2/mvDramIf.h"+#include "ctrlEnv/sys/mvCpuIf.h"++++#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++/* DRAM bank presence encoding */+#define BANK_PRESENT_CS0				0x1+#define BANK_PRESENT_CS0_CS1			0x3+#define BANK_PRESENT_CS0_CS2			0x5+#define BANK_PRESENT_CS0_CS1_CS2		0x7+#define BANK_PRESENT_CS0_CS2_CS3		0xd+#define BANK_PRESENT_CS0_CS2_CS3_CS4	0xf++/* locals   */+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);+#if defined(MV_INC_BOARD_DDIM)+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);+static MV_U32 sdramModeRegCalc(MV_U32 minCas);+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk, +						 MV_U32 forcedCl);+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, +									  MV_U32 minCas, MV_U32 busClk);+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, +									   MV_U32 busClk);++/*******************************************************************************+* mvDramIfDetect - Prepare DRAM interface configuration values.+*+* DESCRIPTION:+*       This function implements the full DRAM detection and timing +*       configuration for best system performance.+*       Since this routine runs from a ROM device (Boot Flash), its stack +*       resides on RAM, that might be the system DRAM. Changing DRAM +*       configuration values while keeping vital data in DRAM is risky. That+*       is why the function does not preform the configuration setting but +*       prepare those in predefined 32bit registers (in this case IDMA +*       registers are used) for other routine to perform the settings.+*       The function will call for board DRAM SPD information for each DRAM +*       chip select. The function will then analyze those SPD parameters of +*       all DRAM banks in order to decide on DRAM configuration compatible +*       for all DRAM banks.+*       The function will set the CPU DRAM address decode registers.+*       Note: This routine prepares values that will overide configuration of+*       mvDramBasicAsmInit().+*       +* INPUT:+*       forcedCl - Forced CAL Latency. If equal to zero, do not force.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvDramIfDetect(MV_U32 forcedCl)+{+	MV_U32 retVal = MV_OK;	/* return value */+	MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];+	MV_U32  busClk, size, base = 0, i, temp, deviceW, dimmW;+	MV_U8	minCas;+	MV_DRAM_DEC_WIN dramDecWin;++	dramDecWin.addrWin.baseHigh = 0;++	busClk = mvBoardSysClkGet();+	+	if (0 == busClk)+	{+		mvOsPrintf("Dram: ERR. Can't detect system clock! \n");+		return MV_ERROR;+	}+	+	/* Close DRAM banks except bank 0 (in case code is excecuting from it...) */+#if defined(MV_INCLUDE_SDRAM_CS1)+	for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)+		mvCpuIfTargetWinEnable(i, MV_FALSE);+#endif++	/* we will use bank 0 as the representative of the all the DRAM banks,  */+	/* since bank 0 must exist.                                             */	+	for(i = 0; i < MV_DRAM_MAX_CS; i++)+	{ +		/* if Bank exist */+		if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))+		{+			/* check it isn't SDRAM */+			if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)+			{+				mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");+				return MV_ERROR;+			}+			/* All banks must support registry in order to activate it */+			if(bankInfo[i].registeredAddrAndControlInputs != +			   bankInfo[0].registeredAddrAndControlInputs)+			{+				mvOsPrintf("Dram: ERR. different Registered settings !!!\n");+				return MV_ERROR;+			}++			/* Init the CPU window decode */+			/* Note that the size in Bank info is in MB units 			*/+			/* Note that the Dimm width might be different then the device DRAM width */+			temp = MV_REG_READ(SDRAM_CONFIG_REG);+			+			deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;+			dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);+			size = ((bankInfo[i].size << 20) / (dimmW/deviceW)); ++			/* We can not change DRAM window settings while excecuting  	*/+			/* code from it. That is why we skip the DRAM CS[0], saving     */+			/* it to the ROM configuration routine	*/+			if(i == SDRAM_CS0)+			{+				MV_U32 sizeToReg;+				+				/* Translate the given window size to register format */+				sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);++				/* Size parameter validity check. */+				if (-1 == sizeToReg)+				{+					mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"+							   ,i);+					return MV_BAD_PARAM;+				}+                +				/* Size is located at upper 16 bits */+				sizeToReg <<= SCSR_SIZE_OFFS;++				/* enable it */+				sizeToReg |= SCSR_WIN_EN;++				MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);+			}+			else+			{+				dramDecWin.addrWin.baseLow = base;+				dramDecWin.addrWin.size = size;+				dramDecWin.enable = MV_TRUE;+				+				if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))+				{+					mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", +							   SDRAM_CS0 + i);+					return MV_ERROR;+				}+			}+			+			base += size;++			/* update the suportedCasLatencies mask */+			bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;++		}+		else+		{+			if( i == 0 ) /* bank 0 doesn't exist */+			{+				mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");+				return MV_ERROR;+			}+			else+			{+				DB(mvOsPrintf("Dram: Could not find bank %d\n", i));+				bankInfo[i].size = 0;     /* Mark this bank as non exist */+			}+		}+	}++	/* calculate minimum CAS */+	minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);+	if (0 == minCas) +	{+		mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",+				   (busClk / 1000000));++		if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+		{+			minCas = DDR2_CL_4; /* Continue with this CAS */+			mvOsPrintf("Set default CAS latency 4\n");+		}+		else+		{+			minCas = DDR1_CL_3; /* Continue with this CAS */+			mvOsPrintf("Set default CAS latency 3\n");+		}+	}++	/* calc SDRAM_CONFIG_REG  and save it to temp register */+	temp = sdramConfigRegCalc(&bankInfo[0], busClk);+	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG1, temp);++	/* calc SDRAM_MODE_REG  and save it to temp register */ +	temp = sdramModeRegCalc(minCas);+	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG2, temp);++	/* calc SDRAM_EXTENDED_MODE_REG  and save it to temp register */ +	temp = sdramExtModeRegCalc(&bankInfo[0]);+	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG10, temp);++	/* calc D_UNIT_CONTROL_LOW  and save it to temp register */+	temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas); +	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG3, temp); ++	/* calc SDRAM_ADDR_CTRL_REG  and save it to temp register */+	temp = sdramAddrCtrlRegCalc(&bankInfo[0]);+	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG4, temp);++	/* calc SDRAM_TIMING_CTRL_LOW_REG  and save it to temp register */+	temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);+	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG5, temp);++	/* calc SDRAM_TIMING_CTRL_HIGH_REG  and save it to temp register */+	temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);+	if(-1 == temp)+	{+		mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");+		return MV_ERROR;+	}+	MV_REG_WRITE(DRAM_BUF_REG6, temp);++	/* Config DDR2 On Die Termination (ODT) registers */+	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{+		sdramDDr2OdtConfig(bankInfo);+	}+	+	/* Note that DDR SDRAM Address/Control and Data pad calibration     */+	/* settings is done in mvSdramIfConfig.s                            */++	return retVal;+}++/*******************************************************************************+* minCasCalc - Calculate the Minimum CAS latency which can be used.+*+* DESCRIPTION:+*	Calculate the minimum CAS latency that can be used, base on the DRAM+*	parameters and the SDRAM bus Clock freq.+*+* INPUT:+*	busClk    - the DRAM bus Clock.+*	pBankInfo - bank info parameters.+*+* OUTPUT:+*       None+*+* RETURN:+*       The minimum CAS Latency. The function returns 0 if max CAS latency+*		supported by banks is incompatible with system bus clock frequancy.+*+*******************************************************************************/+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk, +						 MV_U32 forcedCl)+{+	MV_U32 count = 1, j;+	MV_U32 busClkPs = 1000000000 / (busClk / 1000);  /* in ps units */+	MV_U32 startBit, stopBit;+	+	/*     DDR 1:+			*******-******-******-******-******-******-******-******* +			* bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +			*******-******-******-******-******-******-******-******* +	CAS	=	* TBD  |  4   | 3.5  |   3  | 2.5  |  2   | 1.5  |   1  * +			*********************************************************/+	+	/*     DDR 2:+			*******-******-******-******-******-******-******-******* +			* bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +			*******-******-******-******-******-******-******-******* +	CAS	=	* TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * +			*********************************************************/+	+	+	/* If we are asked to use the forced CAL */+	if (forcedCl)+	{+		mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), +													(forcedCl % 10));+	+		if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+		{+			if (forcedCl == 30)+				pBankInfo->suportedCasLatencies = 0x08;+			else if (forcedCl == 40)+				pBankInfo->suportedCasLatencies = 0x10;+			else+			{+				mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n", +						   (forcedCl / 10), (forcedCl % 10));+				pBankInfo->suportedCasLatencies = 0x10;+			}+		}+		else+		{+			if (forcedCl == 15)+				pBankInfo->suportedCasLatencies = 0x02;+			else if (forcedCl == 20)+				pBankInfo->suportedCasLatencies = 0x04;+			else if (forcedCl == 25)+				pBankInfo->suportedCasLatencies = 0x08;+			else if (forcedCl == 30)+				pBankInfo->suportedCasLatencies = 0x10;+			else if (forcedCl == 40)+				pBankInfo->suportedCasLatencies = 0x40;+			else+			{+				mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n", +						   (forcedCl / 10), (forcedCl % 10));+				pBankInfo->suportedCasLatencies = 0x10;+			}+		}+	+		return pBankInfo->suportedCasLatencies;        +	}   +	+	/* go over the supported cas mask from Max Cas down and check if the 	*/+	/* SysClk stands in its time requirments.								*/+	+	+	DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",+								pBankInfo->suportedCasLatencies,busClkPs ));+	for(j = 7; j > 0; j--)+	{+		if((pBankInfo->suportedCasLatencies >> j) & BIT0 )+		{+			/* Reset the bits for CL incompatible for the sysClk            */+			switch (count)+			{+				case 1: +					if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs) +						pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				case 2: +					if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)+						pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				case 3: +					if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)+						pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				default: +					pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					break;+			}+		}+	}+	+	DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",+				  pBankInfo->suportedCasLatencies ));+	+	/* SDRAM DDR1 controller supports CL 1.5 to 3.5 */+	/* SDRAM DDR2 controller supports CL 3 to 5     */+	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{+		startBit = 3;   /* DDR2 support CL start with CL3 (bit 3) */+		stopBit  = 5;   /* DDR2 support CL stops with CL5 (bit 5) */+	}+	else+	{+		startBit = 1;   /* DDR1 support CL start with CL1.5 (bit 3) */+		stopBit  = 4;   /* DDR1 support CL stops with CL3 (bit 4)   */+	}+	+	for(j = startBit; j <= stopBit ; j++)+	{+		if((pBankInfo->suportedCasLatencies >> j) & BIT0 )+		{+			DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));+			return (BIT0 << j);+		}+	}+	+	return 0; +}++/*******************************************************************************+* sdramConfigRegCalc - Calculate sdram config register+*+* DESCRIPTION: Calculate sdram config register optimized value based+*			on the bank info parameters.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram config reg value.+*+*******************************************************************************/+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)+{+	MV_U32 sdramConfig = 0;+	MV_U32 refreshPeriod;+	+	busClk /= 1000000; /* we work with busClk in MHz */+	+	sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);+	+	/* figure out the memory refresh internal */+	switch (pBankInfo->refreshInterval & 0xf)+	{+		case 0x0: /* refresh period is 15.625 usec */+			refreshPeriod = 15625;+			break;+		case 0x1: /* refresh period is 3.9 usec  	*/+			refreshPeriod = 3900;+			break;+		case 0x2: /* refresh period is 7.8 usec 	*/+			refreshPeriod = 7800;+			break;+		case 0x3: /* refresh period is 31.3 usec	*/+			refreshPeriod = 31300;+			break;+		case 0x4: /* refresh period is 62.5 usec	*/+			refreshPeriod = 62500;+			break;+		case 0x5: /* refresh period is 125 usec 	*/+			refreshPeriod = 125000;+			break;+		default:  /* refresh period undefined 					*/+			mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");+			return -1;+	}+	+	/* Now the refreshPeriod is in register format value */+	refreshPeriod = (busClk * refreshPeriod) / 1000;+	+	DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n", +				  refreshPeriod));++	/* make sure the refresh value is only 14 bits */+	if(refreshPeriod > SDRAM_REFRESH_MAX)+	{+		refreshPeriod = SDRAM_REFRESH_MAX;+		DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n", +					  refreshPeriod));+	}+	+	/* Clear the refresh field */+	sdramConfig &= ~SDRAM_REFRESH_MASK;+	+	/* Set new value to refresh field */+	sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);+	+	/*  registered DRAM ? */+	if ( pBankInfo->registeredAddrAndControlInputs )+	{+		/* it's registered DRAM, so set the reg. DRAM bit */+		sdramConfig |= SDRAM_REGISTERED;+		mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");+	}+	+	/* set DDR SDRAM devices configuration */+	sdramConfig &= ~SDRAM_DCFG_MASK;    /* Clear Dcfg field */+	+	switch (pBankInfo->sdramWidth)+	{+		case 8:  /* memory is x8 */+			sdramConfig |= SDRAM_DCFG_X8_DEV;+			DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));+			break;+		case 16:+			sdramConfig |= SDRAM_DCFG_X16_DEV;+			DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));+			break;+		default: /* memory width unsupported */+			mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");+			return -1;+	}++	/* Set static default settings */+	sdramConfig |= SDRAM_CONFIG_DV;+	+	DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",+				  sdramConfig));+	+	return sdramConfig;  +}++/*******************************************************************************+* sdramModeRegCalc - Calculate sdram mode register+*+* DESCRIPTION: Calculate sdram mode register optimized value based+*			on the bank info parameters and the minCas.+*+* INPUT:+*	minCas	  - minimum CAS supported. +*+* OUTPUT:+*       None+*+* RETURN:+*       sdram mode reg value.+*+*******************************************************************************/+static MV_U32 sdramModeRegCalc(MV_U32 minCas)+{+	MV_U32 sdramMode;+		+	sdramMode = MV_REG_READ(SDRAM_MODE_REG);+	+	/* Clear CAS Latency field */+	sdramMode &= ~SDRAM_CL_MASK;+	+	mvOsPrintf("DRAM CAS Latency ");+	+	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{            	+		switch (minCas)+		{+			case DDR2_CL_3: +				sdramMode |= SDRAM_DDR2_CL_3;+				mvOsPrintf("3.\n");+				break;+			case DDR2_CL_4: +				sdramMode |= SDRAM_DDR2_CL_4;+				mvOsPrintf("4.\n");+				break;+			case DDR2_CL_5: +				sdramMode |= SDRAM_DDR2_CL_5;+				mvOsPrintf("5.\n");+				break;+			default:+				mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");+				return -1;+		}+	sdramMode |= DDR2_MODE_REG_DV;+	}+	else	/* DDR1 */+	{+		switch (minCas)+		{			+			case DDR1_CL_1_5: +				sdramMode |= SDRAM_DDR1_CL_1_5;+				mvOsPrintf("1.5\n");+				break;+			case DDR1_CL_2: +				sdramMode |= SDRAM_DDR1_CL_2;+				mvOsPrintf("2\n");+				break;            +			case DDR1_CL_2_5: +				sdramMode |= SDRAM_DDR1_CL_2_5;+				mvOsPrintf("2.5\n");+				break;+			case DDR1_CL_3: +				sdramMode |= SDRAM_DDR1_CL_3;+				mvOsPrintf("3\n");+				break;+			case DDR1_CL_4: +				sdramMode |= SDRAM_DDR1_CL_4;+				mvOsPrintf("4\n");+				break;+			default:+				mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");+				return -1;	+		}+		sdramMode |= DDR1_MODE_REG_DV;		+	}+	+	DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));++	return sdramMode;+}++/*******************************************************************************+* sdramExtModeRegCalc - Calculate sdram Extended mode register+*+* DESCRIPTION: +*		Return sdram Extended mode register value based+*		on the bank info parameters and bank presence.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram Extended mode reg value.+*+*******************************************************************************/+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)+{+	MV_U32 populateBanks = 0;+	int bankNum;+	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{+	/* Represent the populate banks in binary form */+	for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		if (0 != pBankInfo[bankNum].size)+		{+				populateBanks |= (1 << bankNum);+			}+		}+	+		switch(populateBanks)+		{+			case(BANK_PRESENT_CS0):+				return DDR_SDRAM_EXT_MODE_CS0_DV;+		+			case(BANK_PRESENT_CS0_CS1):+				return DDR_SDRAM_EXT_MODE_CS0_DV;+		+			case(BANK_PRESENT_CS0_CS2):+				return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;+		+			case(BANK_PRESENT_CS0_CS1_CS2):+				return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;+		+			case(BANK_PRESENT_CS0_CS2_CS3):+				return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;+		+			case(BANK_PRESENT_CS0_CS2_CS3_CS4):+				return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;+		+			default:+				mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");+				return -1;+		} +	}+	return 0;+}++/*******************************************************************************+* dunitCtrlLowRegCalc - Calculate sdram dunit control low register+*+* DESCRIPTION: Calculate sdram dunit control low register optimized value based+*			on the bank info parameters and the minCas.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*	minCas	  - minimum CAS supported. +*+* OUTPUT:+*       None+*+* RETURN:+*       sdram dunit control low reg value.+*+*******************************************************************************/+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)+{+	MV_U32 dunitCtrlLow;+	+	dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);+	+	/* Clear StBurstDel field */+	dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;+	+#ifdef MV_88W8660+	/* Clear address/control output timing field */+	dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;+#endif /* MV_88W8660 */++	DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));+	+	/* For proper sample of read data set the Dunit Control register's      */+	/* stBurstDel bits [27:24]                                              */+			/********-********-********-********-********-*********+			* CL=1.5 |  CL=2  | CL=2.5 |  CL=3  |  CL=4  |  CL=5  *+			*********-********-********-********-********-*********+Not Reg.	*  0011  |  0011  |  0100  |  0100  |  0101  |  TBD   *+			*********-********-********-********-********-*********+Registered	*  0100  |  0100  |  0101  |  0101  |  0110  |  TBD   *+			*********-********-********-********-********-*********/+    +	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{+		switch (minCas)+		{+			case DDR2_CL_3: +					/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE) 		+					dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;+				break;+			case DDR2_CL_4: +				/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE) 		+					dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;	+				break;+			default:+				mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", +						   minCas);+				return -1;+		}+	}+	else    /* DDR1 */+	{+		switch (minCas)+		{+			case DDR1_CL_1_5: +				/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+					dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;+				break;+			case DDR1_CL_2: +				/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+					dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;+				break;+			case DDR1_CL_2_5: +				/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+					dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;	+				break;+			case DDR1_CL_3: +				/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+					dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;	+				break;+			case DDR1_CL_4: +				/* registerd DDR SDRAM? */+				if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+					dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;+				else+					dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;	+				break;+			default:+				mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", +						   minCas);+				return -1;+	}+	+	}+	DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));++	return dunitCtrlLow;+}  +                                                                    +/*******************************************************************************+* sdramAddrCtrlRegCalc - Calculate sdram address control register+*+* DESCRIPTION: Calculate sdram address control register optimized value based+*			on the bank info parameters and the minCas.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram address control reg value.+*+*******************************************************************************/+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)+{+	MV_U32 addrCtrl = 0;+	+	/* Set Address Control register static configuration bits */+	addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);+	+	/* Set address control default value */+	addrCtrl |= SDRAM_ADDR_CTRL_DV;  +	+	/* Clear DSize field */+	addrCtrl &= ~SDRAM_DSIZE_MASK;+	+	/* Note that density is in MB units */+	switch (pBankInfo->deviceDensity) +	{+		case 128:                 /* 128 Mbit */+			DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));+			addrCtrl |= SDRAM_DSIZE_128Mb;+			break;+		case 256:                 /* 256 Mbit */+			DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));+			addrCtrl |= SDRAM_DSIZE_256Mb;+			break;+		case 512:                /* 512 Mbit */+			DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));+			addrCtrl |= SDRAM_DSIZE_512Mb;+			break;+		default:+			mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",+                       pBankInfo->deviceDensity);+			return -1;+	}+     +	/* SDRAM address control */+	DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));++	return addrCtrl;+}++/*******************************************************************************+* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register+*+* DESCRIPTION: +*       This function calculates sdram timing control low register +*       optimized value based on the bank info parameters and the minCas.+*+* INPUT:+*	    pBankInfo - sdram bank parameters+*       busClk    - Bus clock+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram timinf control low reg value.+*+*******************************************************************************/+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, +                                                MV_U32 minCas, MV_U32 busClk)+{+	MV_U32 tRp  = 0;+	MV_U32 tRrd = 0;+	MV_U32 tRcd = 0;+	MV_U32 tRas = 0;+	MV_U32 tWr  = 0;+	MV_U32 tWtr = 0;+	MV_U32 tRtp = 0;+	+	MV_U32 bankNum;+	+	busClk = busClk / 1000000;    /* In MHz */+	+	/* Scan all DRAM banks to find maximum timing values */+	for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		tRp  = MV_MAX(tRp,  pBankInfo[bankNum].minRowPrechargeTime);+		tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);+		tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);+		tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);+	}+	+	/* Extract timing (in ns) from SPD value. We ignore the tenth ns part.  */+	/* by shifting the data two bits right.                                 */+	tRp  = tRp  >> 2;    /* For example 0x50 -> 20ns                        */+	tRrd = tRrd >> 2;+	tRcd = tRcd >> 2;+	+	/* Extract clock cycles from time parameter. We need to round up        */+	tRp  = ((busClk * tRp)  / 1000) + (((busClk * tRp)  % 1000) ? 1 : 0);+	/* Micron work around for 133MHz */+	if (busClk == 133)+		tRp += 1;+	DB(mvOsPrintf("Dram  Timing Low: tRp = %d ", tRp));+	tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);+	/* JEDEC min reqeirments tRrd = 2 */+	if (tRrd < 2)+		tRrd = 2;+	DB(mvOsPrintf("tRrd = %d ", tRrd));+	tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);+	DB(mvOsPrintf("tRcd = %d ", tRcd));+	tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);+	DB(mvOsPrintf("tRas = %d ", tRas));+	+	/* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2   */+	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{+		/* Scan all DRAM banks to find maximum timing values */+		for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+		{+			tWr  = MV_MAX(tWr,  pBankInfo[bankNum].minWriteRecoveryTime);+			tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);+			tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);+		}+		+		/* Extract timing (in ns) from SPD value. We ignore the tenth ns    */+		/* part by shifting the data two bits right.                        */+		tWr  = tWr  >> 2;    /* For example 0x50 -> 20ns                    */+		tWtr = tWtr >> 2;+		tRtp = tRtp >> 2;+	+		/* Extract clock cycles from time parameter. We need to round up    */+		tWr  = ((busClk * tWr)  / 1000) + (((busClk * tWr)  % 1000) ? 1 : 0);+		DB(mvOsPrintf("tWr = %d ", tWr));+		tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);+		/* JEDEC min reqeirments tWtr = 2 */+		if (tWtr < 2)+			tWtr = 2;+		DB(mvOsPrintf("tWtr = %d ", tWtr));+		tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);+		/* JEDEC min reqeirments tRtp = 2 */+		if (tRtp < 2)+			tRtp = 2;+		DB(mvOsPrintf("tRtp = %d ", tRtp));+	}+	else+	{    +		tWr  = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);+		+		if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))+		{+			tWtr = 2;+		}+		else+		{+			tWtr = 1;+		}+		+		tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */+	}+	+	DB(mvOsPrintf("tWtr = %d\n", tWtr));+	+	/* Note: value of 0 in register means one cycle, 1 means two and so on  */+	return (((tRp  - 1) << SDRAM_TRP_OFFS)	|+			((tRrd - 1) << SDRAM_TRRD_OFFS)	|+			((tRcd - 1) << SDRAM_TRCD_OFFS)	|+			((tRas - 1) << SDRAM_TRAS_OFFS)	|+			((tWr  - 1) << SDRAM_TWR_OFFS)	|+			((tWtr - 1) << SDRAM_TWTR_OFFS)	|+			((tRtp - 1) << SDRAM_TRTP_OFFS));+}++/*******************************************************************************+* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register+*+* DESCRIPTION: +*       This function calculates sdram timing control high register +*       optimized value based on the bank info parameters and the bus clock.+*+* INPUT:+*	    pBankInfo - sdram bank parameters+*       busClk    - Bus clock+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram timinf control high reg value.+*+*******************************************************************************/+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, +                                                                MV_U32 busClk)+{+	MV_U32 tRfc;+	MV_U32 timeNs = 0;+	int bankNum;+	MV_U32 sdramTw2wCyc = 0;+	+	busClk = busClk / 1000000;    /* In MHz */+	+	/* tRfc is different for DDR1 and DDR2. */+	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)+	{+		MV_U32 bankNum;+	+		/* Scan all DRAM banks to find maximum timing values */+		for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+			timeNs = MV_MAX(timeNs,  pBankInfo[bankNum].minRefreshToActiveCmd);+	}+	else+	{+		if (pBankInfo[0].deviceDensity == _1G)+		{+			timeNs = SDRAM_TRFC_1G;+		}+		else+		{+			if (200 == busClk)+			{+				timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;+			}+			else+			{+				timeNs = SDRAM_TRFC_64_512M;+			}+		}+	}+	+	tRfc = ((busClk * timeNs)  / 1000) + (((busClk * timeNs)  % 1000) ? 1 : 0);+	+	DB(mvOsPrintf("Dram  Timing High: tRfc = %d\n", tRfc));++	+	/* Represent the populate banks in binary form */+	for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		if (0 != pBankInfo[bankNum].size)+			sdramTw2wCyc++;+	}++	/* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */	+	if (sdramTw2wCyc > 1)+		sdramTw2wCyc = 1;+	else+		sdramTw2wCyc = 0;++	/* Note: value of 0 in register means one cycle, 1 means two and so on  */+	return ((((tRfc - 1) & SDRAM_TRFC_MASK)	<< SDRAM_TRFC_OFFS)		|+			((SDRAM_TR2R_CYC - 1)			<< SDRAM_TR2R_OFFS)		|+			((SDRAM_TR2WW2R_CYC - 1)		<< SDRAM_TR2W_W2R_OFFS)	|+			(((tRfc - 1) >> 4)				<< SDRAM_TRFC_EXT_OFFS)	|+			(sdramTw2wCyc					<< SDRAM_TW2W_OFFS));+	+}++/*******************************************************************************+* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.+*+* DESCRIPTION: +*       This function config DDR2 On Die Termination (ODT) registers.+*	ODT configuration is done according to DIMM presence:+*	+*       Presence	  Ctrl Low    Ctrl High  Dunit Ctrl   Ext Mode  +*	CS0	         0x84210000  0x00000000  0x0000780F  0x00000440 +*	CS0+CS1          0x84210000  0x00000000  0x0000780F  0x00000440 +*	CS0+CS2	    	 0x030C030C  0x00000000  0x0000740F  0x00000404 +*	CS0+CS1+CS2	 0x030C030C  0x00000000  0x0000740F  0x00000404 +*	CS0+CS2+CS3	 0x030C030C  0x00000000  0x0000740F  0x00000404 +*	CS0+CS1+CS2+CS3  0x030C030C  0x00000000  0x0000740F  0x00000404 +*		+* INPUT:+*		pBankInfo - bank info parameters.+*+* OUTPUT:+*       None+*+* RETURN:+*       None+*******************************************************************************/+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)+{+	MV_U32 populateBanks = 0;+	MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;+	int bankNum;+	+	/* Represent the populate banks in binary form */+	for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		if (0 != pBankInfo[bankNum].size)+		{+				populateBanks |= (1 << bankNum);+			}+		}+	+	switch(populateBanks)+	{+		case(BANK_PRESENT_CS0):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;+			break;+		case(BANK_PRESENT_CS0_CS1):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;+			break;+		case(BANK_PRESENT_CS0_CS2):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;+			break;+		case(BANK_PRESENT_CS0_CS1_CS2):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;+			break;+		case(BANK_PRESENT_CS0_CS2_CS3):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;+			break;+		case(BANK_PRESENT_CS0_CS2_CS3_CS4):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;+			break;+		default:+			mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");+			return;+	} +	MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);+	MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);+	MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);+	return;+}+#endif /* defined(MV_INC_BOARD_DDIM) */++/*******************************************************************************+* mvDramIfWinSet - Set DRAM interface address decode window+*+* DESCRIPTION: +*       This function sets DRAM interface address decode window.+*+* INPUT:+*	    target      - System target. Use only SDRAM targets.+*       pAddrDecWin - SDRAM address window structure.+*+* OUTPUT:+*       None+*+* RETURN:+*       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK+*       otherwise.+*******************************************************************************/+MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)+{+	MV_U32 baseReg=0,sizeReg=0;+	MV_U32 baseToReg=0 , sizeToReg=0;++    /* Check parameters */+	if (!MV_TARGET_IS_DRAM(target))+	{+		mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);+		return MV_BAD_PARAM;+	}++    /* Check if the requested window overlaps with current enabled windows	*/+    if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))+	{+        mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);+		return MV_BAD_PARAM;+	}++	/* check if address is aligned to the size */+	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))+	{+		mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\+				   "\nAddress 0x%08x is unaligned to size 0x%x.\n",+                   target, +				   pAddrDecWin->addrWin.baseLow,+				   pAddrDecWin->addrWin.size);+		return MV_ERROR;+	}++	/* read base register*/+	baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));++	/* read size register */+	sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));++	/* BaseLow[31:16] => base register [31:16]		*/+	baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;++	/* Write to address decode Base Address Register                  */+	baseReg &= ~SCBAR_BASE_MASK;+	baseReg |= baseToReg;++	/* Translate the given window size to register format			*/+	sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);++	/* Size parameter validity check.                                   */+	if (-1 == sizeToReg)+	{+		mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);+		return MV_BAD_PARAM;+	}++	/* set size */+	sizeReg &= ~SCSR_SIZE_MASK;+	/* Size is located at upper 16 bits */+	sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);++	/* enable/Disable */+	if (MV_TRUE == pAddrDecWin->enable)+	{+		sizeReg |= SCSR_WIN_EN;+	}+	else+	{+		sizeReg &= ~SCSR_WIN_EN;+	}++	/* 3) Write to address decode Base Address Register                   */+	MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);++	/* Write to address decode Size Register                        	*/+	MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);+	+	return MV_OK;+}+/*******************************************************************************+* mvDramIfWinGet - Get DRAM interface address decode window+*+* DESCRIPTION: +*       This function gets DRAM interface address decode window.+*+* INPUT:+*	    target - System target. Use only SDRAM targets.+*+* OUTPUT:+*       pAddrDecWin - SDRAM address window structure.+*+* RETURN:+*       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK+*       otherwise.+*******************************************************************************/+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)+{+	MV_U32 baseReg,sizeReg;+	MV_U32 sizeRegVal;++	/* Check parameters */+	if (!MV_TARGET_IS_DRAM(target))+	{+		mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);+		return MV_ERROR;+	}++	/* Read base and size registers */+	sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));+	baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));++	sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;++	pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,+											 SCSR_SIZE_ALIGNMENT);++    /* Check if ctrlRegToSize returned OK */+	if (-1 == pAddrDecWin->addrWin.size)+	{+		mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);+		return MV_ERROR;+	}++	/* Extract base address						*/+	/* Base register [31:16] ==> baseLow[31:16] 		*/+	pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;++	pAddrDecWin->addrWin.baseHigh =  0;+++	if (sizeReg & SCSR_WIN_EN)+	{+		pAddrDecWin->enable = MV_TRUE;+	}+	else+	{+		pAddrDecWin->enable = MV_FALSE;			+	}++	return MV_OK;+}+/*******************************************************************************+* mvDramIfWinEnable - Enable/Disable SDRAM address decode window+*+* DESCRIPTION: +*		This function enable/Disable SDRAM address decode window.+*+* INPUT:+*	    target - System target. Use only SDRAM targets.+*+* OUTPUT:+*		None.+*+* RETURN:+*		MV_ERROR in case function parameter are invalid, MV_OK otherewise.+*+*******************************************************************************/+MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)+{+	MV_DRAM_DEC_WIN 	addrDecWin;++	/* Check parameters */+	if (!MV_TARGET_IS_DRAM(target))+	{+		mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);+		return MV_ERROR;+	}++	if (enable == MV_TRUE) +	{   /* First check for overlap with other enabled windows				*/+		if (MV_OK != mvDramIfWinGet(target, &addrDecWin))+		{+			mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n", +                                                                        target);+			return MV_ERROR;+		}+		/* Check for overlapping */+		if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))+		{+			/* No Overlap. Enable address decode winNum window              */+			MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);+		}+		else+		{   /* Overlap detected	*/+			mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",+                                                                        target);+			return MV_ERROR;+		}+	}+	else+	{   /* Disable address decode winNum window                             */+		MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);+	}++	return MV_OK;+}++/*******************************************************************************+* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window+*+* DESCRIPTION:+*		This function scan each SDRAM address decode window to test if it +*		overlapps the given address windoow +*+* INPUT:+*       target      - SDRAM target where the function skips checking.+*       pAddrDecWin - The tested address window for overlapping with +*					  SDRAM windows.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if the given address window overlaps any enabled address+*       decode map, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)+{+	MV_TARGET	targetNum;+	MV_DRAM_DEC_WIN 	addrDecWin;+	+	for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)+	{+		/* don't check our winNum or illegal targets */+		if (targetNum == target)+		{+			continue;+		}+		+		/* Get window parameters 	*/+		if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))+		{+			mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");+			return MV_ERROR;+		}+	+		/* Do not check disabled windows	*/+		if (MV_FALSE == addrDecWin.enable)+		{+			continue;+		}+	+		if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))+		{                    +			mvOsPrintf(+			"sdramIfWinOverlap: Required target %d overlap winNum %d\n", +			target, targetNum);+			return MV_TRUE;           +		}+	}+	+	return MV_FALSE;+}++/*******************************************************************************+* mvDramIfBankSizeGet - Get DRAM interface bank size.+*+* DESCRIPTION:+*       This function returns the size of a given DRAM bank.+*+* INPUT:+*       bankNum - Bank number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       DRAM bank size. If bank is disabled the function return '0'. In case +*		or paramter is invalid, the function returns -1.+*+*******************************************************************************/+MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)+{+    MV_DRAM_DEC_WIN 	addrDecWin;+	+	/* Check parameters */+	if (!MV_TARGET_IS_DRAM(bankNum))+	{+		mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);+		return -1;+	}+	/* Get window parameters 	*/+	if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))+	{+		mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");+		return -1;+	}+	+	if (MV_TRUE == addrDecWin.enable)+	{+		return addrDecWin.addrWin.size;+	}+	else+	{+		return 0;+	}+}+++/*******************************************************************************+* mvDramIfSizeGet - Get DRAM interface total size.+*+* DESCRIPTION:+*       This function get the DRAM total size.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       DRAM total size. In case or paramter is invalid, the function +*		returns -1.+*+*******************************************************************************/+MV_32 mvDramIfSizeGet(MV_VOID)+{+	MV_U32 totalSize = 0, bankSize = 0, bankNum;+	+	for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		bankSize = mvDramIfBankSizeGet(bankNum);++		if (-1 == bankSize)+		{+			mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);+			return -1;+		}+		else+		{+			totalSize += bankSize;+		}+	}+	+	DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));+	+	return totalSize;+}++/*******************************************************************************+* mvDramIfBankBaseGet - Get DRAM interface bank base.+*+* DESCRIPTION:+*       This function returns the 32 bit base address of a given DRAM bank.+*+* INPUT:+*       bankNum - Bank number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       DRAM bank size. If bank is disabled or paramter is invalid, the +*		function returns -1.+*+*******************************************************************************/+MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)+{+    MV_DRAM_DEC_WIN 	addrDecWin;+	+	/* Check parameters */+	if (!MV_TARGET_IS_DRAM(bankNum))+	{+		mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);+		return -1;+	}+	/* Get window parameters 	*/+	if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))+	{+		mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");+		return -1;+	}+	+	if (MV_TRUE == addrDecWin.enable)+	{+		return addrDecWin.addrWin.baseLow;+	}+	else+	{+		return -1;+	}+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h	2010-11-09 20:28:10.692495407 +0100@@ -0,0 +1,192 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvDramIfConfigh+#define __INCmvDramIfConfigh++/* includes */++/* defines  */++/* registers defaults values */++#define SDRAM_CONFIG_DV 				\+		(SDRAM_PERR_WRITE			|	\+		 SDRAM_SRMODE				|	\+		 SDRAM_SRCLK_GATED)++#define SDRAM_DUNIT_CTRL_LOW_DV			\+		(SDRAM_CTRL_POS_RISE		|	\+		 SDRAM_CLK1DRV_NORMAL		|	\+		 SDRAM_LOCKEN_ENABLE)++#define SDRAM_ADDR_CTRL_DV	    0+		+#define SDRAM_TIMING_CTRL_LOW_REG_DV 	\+		((0x2 << SDRAM_TRCD_OFFS)	|	\+		 (0x2 << SDRAM_TRP_OFFS)	|	\+		 (0x1 << SDRAM_TWR_OFFS)	|	\+		 (0x0 << SDRAM_TWTR_OFFS)	|	\+		 (0x5 << SDRAM_TRAS_OFFS)	|	\+		 (0x1 << SDRAM_TRRD_OFFS))+/* TRFC 0x27, TW2W 0x1 */+#define SDRAM_TIMING_CTRL_HIGH_REG_DV	(( 0x7 << SDRAM_TRFC_OFFS )	|\+					( 0x2 << SDRAM_TRFC_EXT_OFFS)	|\+					( 0x1 << SDRAM_TW2W_OFFS))++#define SDRAM_OPEN_PAGES_CTRL_REG_DV	SDRAM_OPEN_PAGE_EN	++/* DDR2 ODT default register values */++/* Presence	     Ctrl Low    Ctrl High  Dunit Ctrl   Ext Mode     */+/*	CS0	         0x84210000  0x00000000  0x0000780F  0x00000440 */+/*	CS0+CS1          0x84210000  0x00000000  0x0000780F  0x00000440 */+/*	CS0+CS2	    	 0x030C030C  0x00000000  0x0000740F  0x00000404 */+/*	CS0+CS1+CS2	 0x030C030C  0x00000000  0x0000740F  0x00000404 */+/*	CS0+CS2+CS3	 0x030C030C  0x00000000  0x0000740F  0x00000404 */+/*	CS0+CS1+CS2+CS3  0x030C030C  0x00000000  0x0000740F  0x00000404 */++#define DDR2_ODT_CTRL_LOW_CS0_DV	0x84210000+#define DDR2_ODT_CTRL_HIGH_CS0_DV	0x00000000+#define DDR2_DUNIT_ODT_CTRL_CS0_DV	0x0000780F+#define DDR_SDRAM_EXT_MODE_CS0_DV	0x00000440++#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV	0x030C030C+#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV	0x00000000+#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV	0x0000740F+#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV	0x00000404+++/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */+#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV	\+		(1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)+#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV	\+		(3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)+		+		+#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV		\+		(1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)+#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV		\+		(3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)++/* DDR SDRAM Mode Register default value */+#define DDR1_MODE_REG_DV			0x00000000+#define DDR2_MODE_REG_DV			0x00000400++/* DDR SDRAM Timing parameter default values */+#define DDR1_TIMING_LOW_DV           0x11602220+#define DDR1_TIMING_HIGH_DV          0x0000000d++#define DDR2_TIMING_LOW_DV           0x11812220+#define DDR2_TIMING_HIGH_DV          0x0000030f++/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */+#define FTDLL_DDR1_166MHZ           ((0x1 << 0)    | \+                                     (0x7F<< 12)   | \+                                     (0x1 << 22))++#define FTDLL_DDR1_133MHZ           FTDLL_DDR1_166MHZ++#define FTDLL_DDR1_200MHZ           ((0x1 << 0)    | \+                                     (0x1 << 12)   | \+                                     (0x3 << 14)   | \+                                     (0x1 << 18)   | \+                                     (0x1 << 22))+++#define FTDLL_DDR2_166MHZ           ((0x1 << 0)    | \+                                     (0x1 << 12)   | \+                                     (0x1 << 14)   | \+                                     (0x1 << 16)   | \+                                     (0x1 << 19)   | \+                                     (0xF << 20))++#define FTDLL_DDR2_133MHZ           FTDLL_DDR2_166MHZ++#define FTDLL_DDR2_200MHZ           ((0x1 << 0)    | \+                                     (0x1 << 12)   | \+                                     (0x1 << 14)   | \+                                     (0x1 << 16)   | \+                                     (0x1 << 19)   | \+                                     (0xF << 20))++#define FTDLL_DDR2_250MHZ            0x445001++/* Orion 1 B1 and above */+#define FTDLL_DDR1_166MHZ_5181_B1    0x45D001++/* Orion nas */+#define FTDLL_DDR2_166MHZ_5182       0x597001++/* Orion 2 D0 and above */+#define FTDLL_DDR1_166MHZ_5281_D0    0x8D0001+#define FTDLL_DDR1_200MHZ_5281_D0    0x8D0001+#define FTDLL_DDR2_166MHZ_5281_D0    0x485001+#define FTDLL_DDR2_200MHZ_5281_D0    0x485001+#define FTDLL_DDR2_250MHZ_5281_D0    0x445001+#define FTDLL_DDR2_200MHZ_5281_D1    0x995001+#define FTDLL_DDR2_250MHZ_5281_D1    0x984801++#endif /* __INCmvDramIfh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h	2010-11-09 20:28:10.747105889 +0100@@ -0,0 +1,179 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvDramIfh+#define __INCmvDramIfh++/* includes */+#include "ddr1_2/mvDramIfRegs.h"+#include "ddr1_2/mvDramIfConfig.h"+#include "ctrlEnv/mvCtrlEnvLib.h"++/* defines  */+/* DRAM Timing parameters */+#define SDRAM_TWR                    15  /* ns tWr */+#define SDRAM_TRFC_64_512M_AT_200MHZ 70  /* ns tRfc for dens 64-512 @ 200MHz */+#define SDRAM_TRFC_64_512M           75  /* ns tRfc for dens 64-512          */+#define SDRAM_TRFC_1G                120 /* ns tRfc for dens 1GB             */+#define SDRAM_TR2R_CYC               1   /* cycle for tR2r                   */+#define SDRAM_TR2WW2R_CYC            1   /* cycle for tR2wW2r                */++/* typedefs */++/* enumeration for memory types */+typedef enum _mvMemoryType+{+    MEM_TYPE_SDRAM,+    MEM_TYPE_DDR1,+    MEM_TYPE_DDR2+}MV_MEMORY_TYPE;++/* enumeration for DDR1 supported CAS Latencies */+typedef enum _mvDimmDdr1Cas+{+    DDR1_CL_1_5  = 0x02, +    DDR1_CL_2    = 0x04, +    DDR1_CL_2_5  = 0x08, +    DDR1_CL_3    = 0x10, +    DDR1_CL_4    = 0x40, +    DDR1_CL_FAULT+} MV_DIMM_DDR1_CAS;++/* enumeration for DDR2 supported CAS Latencies */+typedef enum _mvDimmDdr2Cas+{+    DDR2_CL_3    = 0x08, +    DDR2_CL_4    = 0x10, +    DDR2_CL_5    = 0x20, +    DDR2_CL_FAULT+} MV_DIMM_DDR2_CAS;+++typedef struct _mvDramBankInfo+{+    MV_MEMORY_TYPE  memoryType; 	/* DDR1, DDR2 or SDRAM */++    /* DIMM dimensions */+    MV_U32  numOfRowAddr;+    MV_U32  numOfColAddr;+    MV_U32  dataWidth;+    MV_U32  errorCheckType;             /* ECC , PARITY..*/+    MV_U32  sdramWidth;                 /* 4,8,16 or 32 */+    MV_U32  errorCheckDataWidth;        /* 0 - no, 1 - Yes */+    MV_U32  burstLengthSupported;+    MV_U32  numOfBanksOnEachDevice;+    MV_U32  suportedCasLatencies;+    MV_U32  refreshInterval;++    /* DIMM timing parameters */+    MV_U32  minCycleTimeAtMaxCasLatPs;	+    MV_U32  minCycleTimeAtMaxCasLatMinus1Ps;+    MV_U32  minCycleTimeAtMaxCasLatMinus2Ps;+	MV_U32  minRowPrechargeTime;+	MV_U32  minRowActiveToRowActive;+	MV_U32  minRasToCasDelay;+	MV_U32  minRasPulseWidth;+    MV_U32  minWriteRecoveryTime;   /* DDR2 only */+    MV_U32  minWriteToReadCmdDelay; /* DDR2 only */+    MV_U32  minReadToPrechCmdDelay; /* DDR2 only */+    MV_U32  minRefreshToActiveCmd;  /* DDR2 only */+                      +    /* Parameters calculated from the extracted DIMM information */+    MV_U32  size;+    MV_U32  deviceDensity;           	/* 16,64,128,256 or 512 Mbit */+    MV_U32  numberOfDevices;++    /* DIMM attributes (MV_TRUE for yes) */+    MV_BOOL registeredAddrAndControlInputs;+     +}MV_DRAM_BANK_INFO;++/* This structure describes CPU interface address decode window               */+typedef struct _mvDramIfDecWin +{+	MV_ADDR_WIN   addrWin;    /* An address window*/+	MV_BOOL       enable;     /* Address decode window is enabled/disabled    */+}MV_DRAM_DEC_WIN;++#include "ddr1_2/mvDram.h"++/* mvDramIf.h API list */+MV_VOID   mvDramIfBasicAsmInit(MV_VOID);+MV_STATUS mvDramIfDetect(MV_U32 forcedCl);+MV_VOID   _mvDramIfConfig(MV_VOID);++MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);+MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);+MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);+MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);+MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);+MV_32 mvDramIfSizeGet(MV_VOID);++#if 0+MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);+MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);+#endif++#endif /* __INCmvDramIfh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h	2010-11-09 20:28:10.772495655 +0100@@ -0,0 +1,306 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDramIfRegsh+#define __INCmvDramIfRegsh+++/* DDR SDRAM Controller Address Decode Registers */+/* SDRAM CSn Base Address Register (SCBAR) */+#define SDRAM_BASE_ADDR_REG(csNum)	(0x1500 + (csNum * 8))+#define SCBAR_BASE_OFFS				16 +#define SCBAR_BASE_MASK				(0xffff << SCBAR_BASE_OFFS)+#define SCBAR_BASE_ALIGNMENT		0x10000 ++/* SDRAM CSn Size Register (SCSR) */		  +#define SDRAM_SIZE_REG(csNum)	(0x1504 + (csNum * 8))+#define SCSR_WIN_EN					BIT0+#define SCSR_SIZE_OFFS				16+#define SCSR_SIZE_MASK				(0xffff << SCSR_SIZE_OFFS)+#define SCSR_SIZE_ALIGNMENT			0x10000++/* configuration register */+#define SDRAM_CONFIG_REG   		0x1400+#define SDRAM_REFRESH_OFFS 		0+#define SDRAM_REFRESH_MAX  		0x3000+#define SDRAM_REFRESH_MASK 		(SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)+#define SDRAM_DWIDTH_OFFS       14+#define SDRAM_DWIDTH_MASK       (3 << SDRAM_DWIDTH_OFFS)+#define SDRAM_DWIDTH_16BIT      (1 << SDRAM_DWIDTH_OFFS)+#define SDRAM_DWIDTH_32BIT      (2 << SDRAM_DWIDTH_OFFS)+#define SDRAM_DTYPE_OFFS        16+#define SDRAM_DTYPE_MASK        (1 << SDRAM_DTYPE_OFFS)+#define SDRAM_DTYPE_DDR1        (0 << SDRAM_DTYPE_OFFS)+#define SDRAM_DTYPE_DDR2        (1 << SDRAM_DTYPE_OFFS)+#define SDRAM_REGISTERED   		(1 << 17)+#define SDRAM_PERR_OFFS    		18+#define SDRAM_PERR_MASK    		(1 << SDRAM_PERR_OFFS)+#define SDRAM_PERR_NO_WRITE     (0 << SDRAM_PERR_OFFS)+#define SDRAM_PERR_WRITE        (1 << SDRAM_PERR_OFFS)+#define SDRAM_DCFG_OFFS     	20+#define SDRAM_DCFG_MASK     	(0x3 << SDRAM_DCFG_OFFS)+#define SDRAM_DCFG_X16_DEV   	(1 << SDRAM_DCFG_OFFS)+#define SDRAM_DCFG_X8_DEV   	(2 << SDRAM_DCFG_OFFS)+#define SDRAM_SRMODE			(1 << 24)+#define SDRAM_SRCLK_OFFS		25+#define SDRAM_SRCLK_MASK		(1 << SDRAM_SRCLK_OFFS)+#define SDRAM_SRCLK_KEPT		(0 << SDRAM_SRCLK_OFFS)+#define SDRAM_SRCLK_GATED		(1 << SDRAM_SRCLK_OFFS)+#define SDRAM_CATTH_OFFS		26+#define SDRAM_CATTHR_EN			(1 << SDRAM_CATTH_OFFS)+++/* dunit control register */+#define SDRAM_DUNIT_CTRL_REG  	0x1404+#define SDRAM_CTRL_POS_OFFS	   	6+#define SDRAM_CTRL_POS_FALL	   	(0 << SDRAM_CTRL_POS_OFFS)+#define SDRAM_CTRL_POS_RISE	   	(1 << SDRAM_CTRL_POS_OFFS)+#define SDRAM_CLK1DRV_OFFS      12+#define SDRAM_CLK1DRV_MASK      (1 << SDRAM_CLK1DRV_OFFS)+#define SDRAM_CLK1DRV_HIGH_Z    (0 << SDRAM_CLK1DRV_OFFS)+#define SDRAM_CLK1DRV_NORMAL    (1 << SDRAM_CLK1DRV_OFFS)+#define SDRAM_LOCKEN_OFFS       18+#define SDRAM_LOCKEN_MASK       (1 << SDRAM_LOCKEN_OFFS)+#define SDRAM_LOCKEN_DISABLE    (0 << SDRAM_LOCKEN_OFFS)+#define SDRAM_LOCKEN_ENABLE     (1 << SDRAM_LOCKEN_OFFS)+#define SDRAM_ST_BURST_DEL_OFFS 	24+#define SDRAM_ST_BURST_DEL_MAX 	0xf+#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)++/* sdram timing control low register */+#define SDRAM_TIMING_CTRL_LOW_REG	0x1408+#define SDRAM_TRCD_OFFS 		4+#define SDRAM_TRCD_MASK 		(0xF << SDRAM_TRCD_OFFS)+#define SDRAM_TRP_OFFS 			8+#define SDRAM_TRP_MASK 			(0xF << SDRAM_TRP_OFFS)+#define SDRAM_TWR_OFFS 			12+#define SDRAM_TWR_MASK 			(0xF << SDRAM_TWR_OFFS)+#define SDRAM_TWTR_OFFS 		16+#define SDRAM_TWTR_MASK 		(0xF << SDRAM_TWTR_OFFS)+#define SDRAM_TRAS_OFFS 		20+#define SDRAM_TRAS_MASK 		(0xF << SDRAM_TRAS_OFFS)+#define SDRAM_TRRD_OFFS 		24+#define SDRAM_TRRD_MASK 		(0xF << SDRAM_TRRD_OFFS)+#define SDRAM_TRTP_OFFS 		28+#define SDRAM_TRTP_MASK 		(0xF << SDRAM_TRTP_OFFS)++/* sdram timing control high register */+#define SDRAM_TIMING_CTRL_HIGH_REG	0x140c+#define SDRAM_TRFC_OFFS 		0+#define SDRAM_TRFC_MASK 		(0xF << SDRAM_TRFC_OFFS)+#define SDRAM_TR2R_OFFS 		4+#define SDRAM_TR2R_MASK 		(0x3 << SDRAM_TR2R_OFFS)+#define SDRAM_TR2W_W2R_OFFS 		6+#define SDRAM_TR2W_W2R_MASK 		(0x3 << SDRAM_TR2W_W2R_OFFS)+#define SDRAM_TRFC_EXT_OFFS		8+#define SDRAM_TRFC_EXT_MASK		(0x1 << SDRAM_TRFC_EXT_OFFS)+#define SDRAM_TW2W_OFFS		    10+#define SDRAM_TW2W_MASK		    (0x1 << SDRAM_TW2W_OFFS)++/* address control register */+#define SDRAM_ADDR_CTRL_REG		0x1410+#define SDRAM_DSIZE_OFFS   	    4+#define SDRAM_DSIZE_MASK   	    (0x3 << SDRAM_DSIZE_OFFS)+#define SDRAM_DSIZE_128Mb 	    (0x0 << SDRAM_DSIZE_OFFS)+#define SDRAM_DSIZE_256Mb 	    (0x1 << SDRAM_DSIZE_OFFS)+#define SDRAM_DSIZE_512Mb  	    (0x2 << SDRAM_DSIZE_OFFS)++/* SDRAM Open Pages Control registers */+#define SDRAM_OPEN_PAGE_CTRL_REG	0x1414+#define SDRAM_OPEN_PAGE_EN		    (0 << 0)+#define SDRAM_OPEN_PAGE_DIS		    (1 << 0)++/* sdram opertion register */+#define SDRAM_OPERATION_REG 	0x1418+#define SDRAM_CMD_OFFS  		0+#define SDRAM_CMD_MASK   		(0x7 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_NORMAL 		(0x0 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_REFRESH_ALL 	(0x2 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_REG_SET_CMD 	(0x3 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_EXT_MODE_SET 	(0x4 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_NOP 			(0x5 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_SLF_RFRSH 	(0x7 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_EMRS2_CMD  	(0x8 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_EMRS3_CMD  	(0x9 << SDRAM_CMD_OFFS)++/* sdram mode register */+#define SDRAM_MODE_REG 			0x141c+#define SDRAM_BURST_LEN_OFFS 	0+#define SDRAM_BURST_LEN_MASK 	(0x7 << SDRAM_BURST_LEN_OFFS)+#define SDRAM_BURST_LEN_4    	(0x2 << SDRAM_BURST_LEN_OFFS)+#define SDRAM_CL_OFFS   		4+#define SDRAM_CL_MASK   		(0x7 << SDRAM_CL_OFFS)+#define SDRAM_DDR1_CL_2	     	(0x2 << SDRAM_CL_OFFS)+#define SDRAM_DDR1_CL_3      	(0x3 << SDRAM_CL_OFFS)+#define SDRAM_DDR1_CL_4      	(0x4 << SDRAM_CL_OFFS)+#define SDRAM_DDR1_CL_1_5    	(0x5 << SDRAM_CL_OFFS)+#define SDRAM_DDR1_CL_2_5    	(0x6 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_3      	(0x3 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_4      	(0x4 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_5    		(0x5 << SDRAM_CL_OFFS)+#define SDRAM_TM_OFFS           7+#define SDRAM_TM_MASK           (1 << SDRAM_TM_OFFS)+#define SDRAM_TM_NORMAL         (0 << SDRAM_TM_OFFS)+#define SDRAM_TM_TEST_MODE      (1 << SDRAM_TM_OFFS)+#define SDRAM_DLL_OFFS          8+#define SDRAM_DLL_MASK          (1 << SDRAM_DLL_OFFS)+#define SDRAM_DLL_NORMAL        (0 << SDRAM_DLL_OFFS)+#define SDRAM_DLL_RESET 	(1 << SDRAM_DLL_OFFS)+#define SDRAM_WR_OFFS		11+#define SDRAM_WR_MAX		7+#define SDRAM_WR_MASK		(SDRAM_WR_MAX << SDRAM_WR_OFFS)+#define SDRAM_PD_OFFS		12+#define SDRAM_PD_MASK		(1 << SDRAM_PD_OFFS) +#define SDRAM_PD_FAST_EXIT	(0 << SDRAM_PD_OFFS) +#define SDRAM_PD_SLOW_EXIT	(1 << SDRAM_PD_OFFS) ++/* DDR SDRAM Extended Mode register (DSEMR) */+#define SDRAM_EXTENDED_MODE_REG	0x1420+#define DSEMR_DLL_ENABLE		(1 << 0)+#define DSEMR_DS_OFFS			1+#define DSEMR_DS_MASK			(1 << DSEMR_DS_OFFS)+#define DSEMR_DS_NORMAL			(0 << DSEMR_DS_OFFS)+#define DSEMR_DS_REDUCED		(1 << DSEMR_DS_OFFS)+#define DSEMR_RTT0_OFFS			2+#define DSEMR_RTT1_OFFS			6+#define DSEMR_RTT_ODT_DISABLE	((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))+#define DSEMR_RTT_ODT_75_OHM	((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))+#define DSEMR_RTT_ODT_150_OHM	((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))+#define DSEMR_OCD_OFFS			7+#define DSEMR_OCD_MASK			(0x7 << DSEMR_OCD_OFFS)+#define DSEMR_OCD_EXIT_CALIB	(0 << DSEMR_OCD_OFFS)+#define DSEMR_OCD_DRIVE1		(1 << DSEMR_OCD_OFFS)+#define DSEMR_OCD_DRIVE0		(2 << DSEMR_OCD_OFFS)+#define DSEMR_OCD_ADJUST_MODE	(4 << DSEMR_OCD_OFFS)+#define DSEMR_OCD_CALIB_DEFAULT	(7 << DSEMR_OCD_OFFS)+#define DSEMR_DQS_OFFS			10+#define DSEMR_DQS_MASK			(1 << DSEMR_DQS_OFFS)+#define DSEMR_DQS_DIFFERENTIAL	(0 << DSEMR_DQS_OFFS)+#define DSEMR_DQS_SINGLE_ENDED	(0 << DSEMR_DQS_OFFS)+#define DSEMR_RDQS_ENABLE		(1 << 11)+#define DSEMR_QOFF_OUTPUT_BUFF_EN	(1 << 12)++/* DDR SDRAM Operation Control Register */+#define SDRAM_OPERATION_CTRL_REG	0x142c++/* Dunit FTDLL Configuration Register */+#define SDRAM_FTDLL_CONFIG_REG			0x1484+  +/* Pads Calibration register */+#define SDRAM_ADDR_CTRL_PADS_CAL_REG	0x14c0+#define SDRAM_DATA_PADS_CAL_REG		0x14c4+#define SDRAM_DRVN_OFFS 				0+#define SDRAM_DRVN_MASK 				(0x3F << SDRAM_DRVN_OFFS)+#define SDRAM_DRVP_OFFS 				6+#define SDRAM_DRVP_MASK 				(0x3F << SDRAM_DRVP_OFFS)+#define SDRAM_PRE_DRIVER_STRENGTH_OFFS	12+#define SDRAM_PRE_DRIVER_STRENGTH_MASK	(3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)+#define SDRAM_TUNE_EN   		BIT16+#define SDRAM_LOCK_OFFS 		17+#define SDRAM_LOCK_MAKS 		(0x1F << SDRAM_LOCK_OFFS)+#define SDRAM_LOCKN_OFFS 		17+#define SDRAM_LOCKN_MAKS 		(0x3F << SDRAM_LOCKN_OFFS)+#define SDRAM_LOCKP_OFFS 		23+#define SDRAM_LOCKP_MAKS 		(0x3F << SDRAM_LOCKP_OFFS)+#define SDRAM_WR_EN     		(1 << 31)++/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */+#define DDR2_SDRAM_ODT_CTRL_LOW_REG  0x1494+#define DSOCLR_ODT_RD_OFFS(odtNum)   (odtNum * 4)+#define DSOCLR_ODT_RD_MASK(odtNum)   (0xf << DSOCLR_ODT_RD_OFFS(odtNum))+#define DSOCLR_ODT_RD(odtNum, bank)  ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))+#define DSOCLR_ODT_WR_OFFS(odtNum)   (16 + (odtNum * 4))+#define DSOCLR_ODT_WR_MASK(odtNum)   (0xf << DSOCLR_ODT_WR_OFFS(odtNum))+#define DSOCLR_ODT_WD(odtNum, bank)  ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))++/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */+#define DDR2_SDRAM_ODT_CTRL_HIGH_REG    0x1498+/* Optional control values to DSOCHR_ODT_EN macro */+#define DDR2_ODT_CTRL_DUNIT         0+#define DDR2_ODT_CTRL_NEVER         1+#define DDR2_ODT_CTRL_ALWAYS        3+#define DSOCHR_ODT_EN_OFFS(odtNum)  (odtNum * 2)+#define DSOCHR_ODT_EN_MASK(odtNum)  (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))+#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))++/* DDR2 Dunit ODT Control Register (DDOCR)*/+#define DDR2_DUNIT_ODT_CONTROL_REG  0x149c+#define DDOCR_ODT_RD_OFFS           0+#define DDOCR_ODT_RD_MASK           (0xf << DDOCR_ODT_RD_OFFS)+#define DDOCR_ODT_RD(bank)          ((1 << bank) << DDOCR_ODT_RD_OFFS)+#define DDOCR_ODT_WR_OFFS           4+#define DDOCR_ODT_WR_MASK           (0xf << DDOCR_ODT_WR_OFFS)+#define DDOCR_ODT_WR(bank)          ((1 << bank) << DDOCR_ODT_WR_OFFS)+#define DSOCR_ODT_EN_OFFS           8+#define DSOCR_ODT_EN_MASK           (0x3 << DSOCR_ODT_EN_OFFS)+#define DSOCR_ODT_EN(ctrl)          ((1 << ctrl) << DSOCR_ODT_EN_OFFS)+#define DSOCR_ODT_SEL_OFFS          10+#define DSOCR_ODT_SEL_MASK          (0x3 << DSOCR_ODT_SEL_OFFS)++/* DDR SDRAM Initialization Control Register (DSICR) */+#define DDR_SDRAM_INIT_CTRL_REG		0x1480+#define DSICR_INIT_EN				(1 << 0)++#endif /* __INCmvDramIfRegsh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c	2010-11-09 20:28:10.812495401 +0100@@ -0,0 +1,1855 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++/* includes */+#include "ddr2/mvDramIf.h"+#include "ctrlEnv/sys/mvCpuIf.h"++#include "ddr2/mvDramIfStaticInit.h"++/* #define MV_DEBUG */+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++/* DRAM bank presence encoding */+#define BANK_PRESENT_CS0			    0x1+#define BANK_PRESENT_CS0_CS1			0x3+#define BANK_PRESENT_CS0_CS2			0x5+#define BANK_PRESENT_CS0_CS1_CS2		0x7+#define BANK_PRESENT_CS0_CS2_CS3		0xd+#define BANK_PRESENT_CS0_CS2_CS3_CS4	0xf++/* locals   */+#ifndef MV_STATIC_DRAM_ON_BOARD+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32  busClk, MV_STATUS TTmode );+static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32  busClk);+static MV_U32 sdramModeRegCalc(MV_U32 minCas);+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);+static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);+static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);+static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);+#endif+MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A++#ifdef MV_INCLUDE_SDRAM_CS1+		,N_A+#endif+#ifdef MV_INCLUDE_SDRAM_CS2+		,N_A+#endif+#ifdef MV_INCLUDE_SDRAM_CS3+    ,N_A+#endif+	};+/* Get DRAM size of CS num */+MV_U32 mvDramCsSizeGet(MV_U32 csNum)+{+	MV_DRAM_BANK_INFO bankInfo;+	MV_U32  size, deviceW, dimmW;+#ifdef MV78XX0	+	MV_U32  temp;+#endif++	if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))+	{+        	if (0 == bankInfo.size)+			return 0;++		/* Note that the Dimm width might be different then the device DRAM width */+#ifdef MV78XX0	+		temp = MV_REG_READ(SDRAM_CONFIG_REG);+		deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;+#else+		deviceW = 16 /* KW family */;+#endif+		dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);+		size = ((bankInfo.size << 20) / (dimmW/deviceW)); +		return size;+	}+	else+		return 0;+}+/*******************************************************************************+* mvDramIfDetect - Prepare DRAM interface configuration values.+*+* DESCRIPTION:+*       This function implements the full DRAM detection and timing +*       configuration for best system performance.+*       Since this routine runs from a ROM device (Boot Flash), its stack +*       resides on RAM, that might be the system DRAM. Changing DRAM +*       configuration values while keeping vital data in DRAM is risky. That+*       is why the function does not preform the configuration setting but +*       prepare those in predefined 32bit registers (in this case IDMA +*       registers are used) for other routine to perform the settings.+*       The function will call for board DRAM SPD information for each DRAM +*       chip select. The function will then analyze those SPD parameters of +*       all DRAM banks in order to decide on DRAM configuration compatible +*       for all DRAM banks.+*       The function will set the CPU DRAM address decode registers.+*       Note: This routine prepares values that will overide configuration of+*       mvDramBasicAsmInit().+*       +* INPUT:+*       forcedCl - Forced CAL Latency. If equal to zero, do not force.+*       eccDisable - Force down the ECC.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)+{+	MV_32 	MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {+		SDRAM_CS0+#ifdef MV_INCLUDE_SDRAM_CS1+		,SDRAM_CS1+#endif+#ifdef MV_INCLUDE_SDRAM_CS2+		,SDRAM_CS2+#endif+#ifdef MV_INCLUDE_SDRAM_CS3+		,SDRAM_CS3+#endif+		};+	MV_U32  busClk, deviceW, dimmW;+	MV_U32 numOfAllDevices = 0;+	MV_STATUS TTMode; +#ifndef MV_STATIC_DRAM_ON_BOARD+	MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];+	MV_U32  size, base = 0, i, j, temp, busClkPs;+	MV_U8	minCas;+	MV_CPU_DEC_WIN dramDecWin;+	dramDecWin.addrWin.baseHigh = 0;+#endif++	busClk = mvBoardSysClkGet();++	if (0 == busClk)+	{+		mvOsPrintf("Dram: ERR. Can't detect system clock! \n");+		return MV_ERROR;+	}+	+#ifndef MV_STATIC_DRAM_ON_BOARD++	busClkPs = 1000000000 / (busClk / 1000);  /* in ps units */+	/* we will use bank 0 as the representative of the all the DRAM banks,  */+	/* since bank 0 must exist.                                             */	+	for(i = 0; i < MV_DRAM_MAX_CS; i++)+	{ +		/* if Bank exist */+		if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))+		{+			DB(mvOsPrintf("Dram: Find bank %d\n", i));+			/* check it isn't SDRAM */+			if(bankInfo[i].memoryType != MEM_TYPE_DDR2)+			{+				mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");+				return MV_ERROR;+			}++            		/* All banks must support the Mclk freqency */+			if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)+			{+				mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);+				return MV_ERROR;+			}++			/* All banks must support registry in order to activate it */+			if(bankInfo[i].registeredAddrAndControlInputs != +			   bankInfo[0].registeredAddrAndControlInputs)+			{+				mvOsOutput("Dram: ERR. different Registered settings !!!\n");+				return MV_ERROR;+			}++			/* All banks must support same ECC mode */+			if(bankInfo[i].errorCheckType != +			   bankInfo[0].errorCheckType)+			{+				mvOsOutput("Dram: ERR. different ECC settings !!!\n");+				return MV_ERROR;+			}++		}+		else+		{+			if( i == 0 ) /* bank 0 doesn't exist */+			{+				mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");+				return MV_ERROR;+			}+			else+			{+				DB(mvOsPrintf("Dram: Could not find bank %d\n", i));+				bankInfo[i].size = 0;     /* Mark this bank as non exist */+			}+		}+	}++#ifdef MV_INCLUDE_SDRAM_CS2+	if (bankInfo[SDRAM_CS0].size <  bankInfo[SDRAM_CS2].size)+	{+		MV_DRAM_CS_order[0] = SDRAM_CS2;+		MV_DRAM_CS_order[1] = SDRAM_CS3;+		MV_DRAM_CS_order[2] = SDRAM_CS0;+		MV_DRAM_CS_order[3] = SDRAM_CS1;+		DRAM_CS_Order[0] = SDRAM_CS2;+		DRAM_CS_Order[1] = SDRAM_CS3;+		DRAM_CS_Order[2] = SDRAM_CS0;+		DRAM_CS_Order[3] = SDRAM_CS1;++	}+	else+#endif+	{+		MV_DRAM_CS_order[0] = SDRAM_CS0;+		MV_DRAM_CS_order[1] = SDRAM_CS1;+		DRAM_CS_Order[0] = SDRAM_CS0;+		DRAM_CS_Order[1] = SDRAM_CS1;+#ifdef MV_INCLUDE_SDRAM_CS2+		MV_DRAM_CS_order[2] = SDRAM_CS2;+		MV_DRAM_CS_order[3] = SDRAM_CS3;+		DRAM_CS_Order[2] = SDRAM_CS2;+		DRAM_CS_Order[3] = SDRAM_CS3;+#endif+	}++	for(j = 0; j < MV_DRAM_MAX_CS; j++)+	{+		i = MV_DRAM_CS_order[j];+		+        	if (0 == bankInfo[i].size)+			continue;++			/* Init the CPU window decode */+			/* Note that the Dimm width might be different then the device DRAM width */+#ifdef MV78XX0	+			temp = MV_REG_READ(SDRAM_CONFIG_REG);+			deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;+#else+			deviceW = 16 /* KW family */;+#endif+			dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);+			size = ((bankInfo[i].size << 20) / (dimmW/deviceW)); +		+			/* We can not change DRAM window settings while excecuting  	*/+			/* code from it. That is why we skip the DRAM CS[0], saving     */+			/* it to the ROM configuration routine				*/++			numOfAllDevices += bankInfo[i].numberOfDevices;+			if (i == MV_DRAM_CS_order[0])+			{+				MV_U32 sizeToReg;+				/* Translate the given window size to register format		*/+				sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);+				/* Size parameter validity check.                           */+				if (-1 == sizeToReg)+				{+					mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"+							   ,i);+					return MV_BAD_PARAM;+				}++				DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)+				sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);+				sizeToReg |= SCSR_WIN_EN;+				MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);+			}+			else+			{+				dramDecWin.addrWin.baseLow = base;+				dramDecWin.addrWin.size = size;+				dramDecWin.enable = MV_TRUE;+				DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));+				+				/* Check if the DRAM size is more then 3GByte */+				if (base < 0xC0000000)+				{+					DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));+           			if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))+					{+						mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);+						return 	MV_ERROR;+					}+				}+			}+			+			base += size;++			/* update the suportedCasLatencies mask */+			bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;+	}++	/* calculate minimum CAS */+	minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);+	if (0 == minCas) +	{+		mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",+				   (busClk / 1000000));++		minCas = DDR2_CL_4; /* Continue with this CAS */+		mvOsOutput("Set default CAS latency 4\n");+	}++	/* calc SDRAM_CONFIG_REG  and save it to temp register */+	temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);+	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");+		return MV_ERROR;+	}++	/* check if ECC is enabled by the user */+	if(eccDisable)	+	{	+		/* turn off ECC*/+		temp &= ~BIT18;+	}+	DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG1, temp);+	+	/* calc SDRAM_MODE_REG  and save it to temp register */ +	temp = sdramModeRegCalc(minCas);+    	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG2, temp);++	/* calc SDRAM_EXTENDED_MODE_REG  and save it to temp register */ +	temp = sdramExtModeRegCalc(&bankInfo[0], busClk);+	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG10, temp);++	/* calc D_UNIT_CONTROL_LOW  and save it to temp register */+	TTMode = MV_FALSE;+	DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)+	if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )+	{+		if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||+			(numOfAllDevices > 18) )+		{+			mvOsOutput("Enable 2T ");+			TTMode = MV_TRUE;+		}+	}++  	temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode ); +   	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)+  	MV_REG_WRITE(DRAM_BUF_REG3, temp); ++	/* calc D_UNIT_CONTROL_HIGH  and save it to temp register */+  	temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk); +   	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)+	/* check if ECC is enabled by the user */+	if(eccDisable)	+	{	+		/* turn off sample stage if no ecc */+		temp &= ~SDRAM__D2P_EN;;+	}+  	MV_REG_WRITE(DRAM_BUF_REG13, temp); ++	/* calc SDRAM_ADDR_CTRL_REG  and save it to temp register */+	temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);+    	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG4, temp);++	/* calc SDRAM_TIMING_CTRL_LOW_REG  and save it to temp register */+	temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);+    	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG5, temp);++	/* calc SDRAM_TIMING_CTRL_HIGH_REG  and save it to temp register */+	temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);+    	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG6, temp);++	sdramDDr2OdtConfig(bankInfo);++	/* calc DDR2_SDRAM_TIMING_LOW_REG  and save it to temp register */+	temp = sdramDdr2TimeLoRegCalc(minCas);+	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG11, temp);++	/* calc DDR2_SDRAM_TIMING_HIGH_REG  and save it to temp register */+	temp = sdramDdr2TimeHiRegCalc(minCas);+	if(-1 == temp)+	{+		mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");+		return MV_ERROR;+	}+	DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)+	MV_REG_WRITE(DRAM_BUF_REG12, temp);+#endif+	+	/* Note that DDR SDRAM Address/Control and Data pad calibration     */+	/* settings is done in mvSdramIfConfig.s                            */++ 	return MV_OK;+}+++/*******************************************************************************+* mvDramIfBankBaseGet - Get DRAM interface bank base.+*+* DESCRIPTION:+*       This function returns the 32 bit base address of a given DRAM bank.+*+* INPUT:+*       bankNum - Bank number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       DRAM bank size. If bank is disabled or paramter is invalid, the +*		function returns -1.+*+*******************************************************************************/+MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)+{+	DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",+				  bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));+	return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);+}++/*******************************************************************************+* mvDramIfBankSizeGet - Get DRAM interface bank size.+*+* DESCRIPTION:+*       This function returns the size of a given DRAM bank.+*+* INPUT:+*       bankNum - Bank number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       DRAM bank size. If bank is disabled the function return '0'. In case +*		or paramter is invalid, the function returns -1.+*+*******************************************************************************/+MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)+{+	DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",+				  bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));+	return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);+}+++/*******************************************************************************+* mvDramIfSizeGet - Get DRAM interface total size.+*+* DESCRIPTION:+*       This function get the DRAM total size.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       DRAM total size. In case or paramter is invalid, the function +*		returns -1.+*+*******************************************************************************/+MV_U32 mvDramIfSizeGet(MV_VOID)+{+	MV_U32 size = 0, i;+	+	for(i = 0; i < MV_DRAM_MAX_CS; i++)+		size += mvDramIfBankSizeGet(i);+	+	DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));+	return size;+}++/*******************************************************************************+* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.+*+* DESCRIPTION:+*       The ECC single bit error threshold is the number of single bit +*       errors to happen before the Dunit generates an interrupt.+*       This function set single bit ECC threshold.+*+* INPUT:+*       threshold - threshold.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if threshold is to big, MV_OK otherwise.+*+*******************************************************************************/+MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)+{+    MV_U32 regVal; ++    if (threshold > SECR_THRECC_MAX)+    {+        return MV_BAD_PARAM;+    }++    regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);+    regVal &= ~SECR_THRECC_MASK;+    regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));+    MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);++    return MV_OK;+}++#ifndef MV_STATIC_DRAM_ON_BOARD+/*******************************************************************************+* minCasCalc - Calculate the Minimum CAS latency which can be used.+*+* DESCRIPTION:+*	Calculate the minimum CAS latency that can be used, base on the DRAM+*	parameters and the SDRAM bus Clock freq.+*+* INPUT:+*	busClk    - the DRAM bus Clock.+*	pBankInfo - bank info parameters.+*	forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.+*+* OUTPUT:+*       None+*+* RETURN:+*       The minimum CAS Latency. The function returns 0 if max CAS latency+*		supported by banks is incompatible with system bus clock frequancy.+*+*******************************************************************************/++static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)+{+	MV_U32 count = 1, j;+	MV_U32 busClkPs = 1000000000 / (busClk / 1000);  /* in ps units */+	MV_U32 startBit, stopBit;+	MV_U32 minCas0 = 0, minCas2 = 0;+	+	+	/*     DDR 2:+			*******-******-******-******-******-******-******-******* +			* bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +			*******-******-******-******-******-******-******-******* +	CAS	=	* TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * +	Disco VI=	* TBD  | TBD  |  5   |  4   |  3   |  TBD   | TBD | TBD * +	Disco Duo=	* TBD  |   6  |  5   |  4   |  3   |  TBD   | TBD | TBD * +			*********************************************************/+	+	+	/* If we are asked to use the forced CAL  we change the suported CAL to be forcedCl only */+	if (forcedCl)+	{+		mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));+	+			if (forcedCl == 30)+				pBankInfo->suportedCasLatencies = 0x08;+			else if (forcedCl == 40)+				pBankInfo->suportedCasLatencies = 0x10;+			else if (forcedCl == 50)+				pBankInfo->suportedCasLatencies = 0x20;+			else if (forcedCl == 60)+				pBankInfo->suportedCasLatencies = 0x40;+			else+			{+				mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n", +						   (forcedCl / 10), (forcedCl % 10));+				pBankInfo->suportedCasLatencies = 0x10;+			}++		return pBankInfo->suportedCasLatencies;        +	}   +	+	/* go over the supported cas mask from Max Cas down and check if the 	*/+	/* SysClk stands in its time requirments.				*/++	DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",+								pBankInfo->suportedCasLatencies,busClkPs ));+	count = 1;+	for(j = 7; j > 0; j--)+	{+		if((pBankInfo->suportedCasLatencies >> j) & BIT0 )+		{+			/* Reset the bits for CL incompatible for the sysClk */+			switch (count)+			{+				case 1: +					if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs) +						pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				case 2: +					if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)+						pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				case 3: +					if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)+						pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				default: +					pBankInfo->suportedCasLatencies &= ~(BIT0 << j);+					break;+			}+		}+	}+	+	DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",+											pBankInfo->suportedCasLatencies ));++	count = 1;+	DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",+								pBankInfo2->suportedCasLatencies,busClkPs ));+	for(j = 7; j > 0; j--)+	{+		if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )+		{+			/* Reset the bits for CL incompatible for the sysClk */+			switch (count)+			{+				case 1: +					if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs) +						pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				case 2: +					if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)+						pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				case 3: +					if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)+						pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);+					count++;+					break;+				default: +					pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);+					break;+			}+		}+	}+	+	DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",+									pBankInfo2->suportedCasLatencies ));++	startBit = 3;   /* DDR2 support CL start with CL3 (bit 3) */+	stopBit  = 6;   /* DDR2 support CL stops with CL6 (bit 6) */++	for(j = startBit; j <= stopBit ; j++)+	{+		if((pBankInfo->suportedCasLatencies >> j) & BIT0 )+		{+			DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));+			minCas0 = (BIT0 << j);+			break;+		}+	}++	for(j = startBit; j <= stopBit ; j++)+	{+		if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )+		{+			DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));+			minCas2 = (BIT0 << j);+			break;+		}+	}+	+	if (minCas2 > minCas0)+		return minCas2;+	else+		return minCas0;+	+	return 0; +}++/*******************************************************************************+* sdramConfigRegCalc - Calculate sdram config register+*+* DESCRIPTION: Calculate sdram config register optimized value based+*			on the bank info parameters.+*+* INPUT:+*	busClk    - the DRAM bus Clock.+*	pBankInfo - sdram bank parameters+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram config reg value.+*+*******************************************************************************/+static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)+{+	MV_U32 sdramConfig = 0;+	MV_U32 refreshPeriod;+	+	busClk /= 1000000; /* we work with busClk in MHz */+	+	sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);+	+	/* figure out the memory refresh internal */+	switch (pBankInfo->refreshInterval & 0xf)+	{+		case 0x0: /* refresh period is 15.625 usec */+				refreshPeriod = 15625;+				break;+		case 0x1: /* refresh period is 3.9 usec  	*/+				refreshPeriod = 3900;+				break;+		case 0x2: /* refresh period is 7.8 usec 	*/+				refreshPeriod = 7800;+				break;+		case 0x3: /* refresh period is 31.3 usec	*/+				refreshPeriod = 31300;+				break;+		case 0x4: /* refresh period is 62.5 usec	*/+				refreshPeriod = 62500;+				break;+		case 0x5: /* refresh period is 125 usec 	*/+				refreshPeriod = 125000;+				break;+		default:  /* refresh period undefined 					*/+				mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");+				return -1;+    }+	+	/* Now the refreshPeriod is in register format value */+	refreshPeriod = (busClk * refreshPeriod) / 1000;+	+	DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n", +				  refreshPeriod));++	/* make sure the refresh value is only 14 bits */+	if(refreshPeriod > SDRAM_REFRESH_MAX)+	{+		refreshPeriod = SDRAM_REFRESH_MAX;+		DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n", +					  refreshPeriod));+	}+	+	/* Clear the refresh field */+	sdramConfig &= ~SDRAM_REFRESH_MASK;+	+	/* Set new value to refresh field */+	sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);+	+	/*  registered DRAM ? */+	if ( pBankInfo->registeredAddrAndControlInputs )+	{+		/* it's registered DRAM, so set the reg. DRAM bit */+		sdramConfig |= SDRAM_REGISTERED;+		DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)+	}++	/* ECC and IERR support */+	sdramConfig &= ~SDRAM_ECC_MASK;    /* Clear ECC field */+	sdramConfig &= ~SDRAM_IERR_MASK;    /* Clear IErr field */++	if ( pBankInfo->errorCheckType ) +	{+		sdramConfig |= SDRAM_ECC_EN;+		sdramConfig |= SDRAM_IERR_REPORTE; +                DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));+	}+	else+	{+                sdramConfig |= SDRAM_ECC_DIS;+		sdramConfig |= SDRAM_IERR_IGNORE; +                DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));+	}+	/* Set static default settings */+	sdramConfig |= SDRAM_CONFIG_DV;+	+	DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",+				  sdramConfig));+	+ 	return sdramConfig;  +}++/*******************************************************************************+* sdramModeRegCalc - Calculate sdram mode register+*+* DESCRIPTION: Calculate sdram mode register optimized value based+*			on the bank info parameters and the minCas.+*+* INPUT:+*	minCas	  - minimum CAS supported. +*+* OUTPUT:+*       None+*+* RETURN:+*       sdram mode reg value.+*+*******************************************************************************/+static MV_U32 sdramModeRegCalc(MV_U32 minCas)+{+	MV_U32 sdramMode;+		+	sdramMode = MV_REG_READ(SDRAM_MODE_REG);+	+	/* Clear CAS Latency field */+	sdramMode &= ~SDRAM_CL_MASK;+	+	DB(mvOsPrintf("DRAM CAS Latency ");)+	+		switch (minCas)+		{+			case DDR2_CL_3: +				sdramMode |= SDRAM_DDR2_CL_3;+				DB(mvOsPrintf("3.\n");)+				break;+			case DDR2_CL_4: +				sdramMode |= SDRAM_DDR2_CL_4;+				DB(mvOsPrintf("4.\n");)+				break;+			case DDR2_CL_5: +				sdramMode |= SDRAM_DDR2_CL_5;+				DB(mvOsPrintf("5.\n");)+				break;+			case DDR2_CL_6: +				sdramMode |= SDRAM_DDR2_CL_6;+				DB(mvOsPrintf("6.\n");)+				break;+			default:+				mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");+				return -1;+        }++	DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));++	return sdramMode;+}+/*******************************************************************************+* sdramExtModeRegCalc - Calculate sdram Extended mode register+*+* DESCRIPTION: +*		Return sdram Extended mode register value based+*		on the bank info parameters and bank presence.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*	busClk - DRAM frequency+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram Extended mode reg value.+*+*******************************************************************************/+static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)+{+	MV_U32 populateBanks = 0;+	int bankNum;++		/* Represent the populate banks in binary form */+		for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+		{+			if (0 != pBankInfo[bankNum].size)+			{+				populateBanks |= (1 << bankNum);+			}+		}+	+		switch(populateBanks)+		{+			case(BANK_PRESENT_CS0):+			case(BANK_PRESENT_CS0_CS1):+				return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;+		+			case(BANK_PRESENT_CS0_CS2):+			case(BANK_PRESENT_CS0_CS1_CS2):+			case(BANK_PRESENT_CS0_CS2_CS3):+			case(BANK_PRESENT_CS0_CS2_CS3_CS4):+				if (busClk >= MV_BOARD_SYSCLK_267MHZ)+				    return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;+				else+				    return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;+		+			default:+				mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");+				return -1;+		} +	return 0;+}++/*******************************************************************************+* dunitCtrlLowRegCalc - Calculate sdram dunit control low register+*+* DESCRIPTION: Calculate sdram dunit control low register optimized value based+*			on the bank info parameters and the minCas.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*	minCas	  - minimum CAS supported. +*+* OUTPUT:+*       None+*+* RETURN:+*       sdram dunit control low reg value.+*+*******************************************************************************/+static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32  busClk, MV_STATUS TTMode)+{+	MV_U32 dunitCtrlLow, cl;+	MV_U32 sbOutR[4]={3,5,7,9} ;+	MV_U32 sbOutU[4]={1,3,5,7} ;+	+    	dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);++        DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));++	/* Clear StBurstOutDel field */+	dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;+	+	/* Clear StBurstInDel field */+	dunitCtrlLow &= ~SDRAM_SB_IN_MASK;++	/* Clear CtrlPos field */+	dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;++	/* Clear 2T field */+	dunitCtrlLow &= ~SDRAM_2T_MASK;+	if (TTMode == MV_TRUE)+	{+		dunitCtrlLow |= SDRAM_2T_MODE;+	}+	+	/* For proper sample of read data set the Dunit Control register's      */+	/* stBurstInDel bits [27:24]                                            */+	/*		200MHz - 267MHz None reg  = CL + 1			*/+	/*		200MHz - 267MHz reg	  = CL + 2			*/+	/*		> 267MHz None reg  = CL + 2			*/+	/*		> 267MHz reg	  = CL + 3			*/+	+	/* For proper sample of read data set the Dunit Control register's      */+	/* stBurstOutDel bits [23:20]                                           */+			/********-********-********-********-+			*  CL=3  |  CL=4  |  CL=5  |  CL=6  |+			*********-********-********-********-+	Not Reg.	*  0001  |  0011  |  0101  |  0111  |+			*********-********-********-********-+	Registered	*  0011  |  0101  |  0111  |  1001  |+			*********-********-********-********/+    +		/* Set Dunit Control low default value */+		dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV; ++		switch (minCas)+		{+			case DDR2_CL_3: cl = 3; break;+			case DDR2_CL_4: cl = 4; break;+			case DDR2_CL_5: cl = 5; break;+			case DDR2_CL_6: cl = 6; break;+			default:+				mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);+				return -1;+		}++		/* registerd DDR SDRAM? */+		if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+		{+			dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;+		}+		else+		{+			dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;+		}++		DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));++		if (busClk <= MV_BOARD_SYSCLK_267MHZ)+		{+			if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+				cl = cl + 2;+			else+				cl = cl + 1;+		}+		else+		{+			if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)+				cl = cl + 3;+			else+				cl = cl + 2;+		}+		+        DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));+		dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;++	DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));++	return dunitCtrlLow;+}  ++/*******************************************************************************+* dunitCtrlHighRegCalc - Calculate sdram dunit control high register+*+* DESCRIPTION: Calculate sdram dunit control high register optimized value based+*			on the bus clock.+*+* INPUT:+*	busClk	  - DRAM frequency. +*+* OUTPUT:+*       None+*+* RETURN:+*       sdram dunit control high reg value.+*+*******************************************************************************/+static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32  busClk)+{+	MV_U32 dunitCtrlHigh;+	dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);+	if(busClk > MV_BOARD_SYSCLK_300MHZ) +		dunitCtrlHigh |= SDRAM__P2D_EN;+	else+		dunitCtrlHigh &= ~SDRAM__P2D_EN;++	if(busClk > MV_BOARD_SYSCLK_267MHZ) +	    dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);++	/* If ECC support we turn on D2P sample */+	dunitCtrlHigh &= ~SDRAM__D2P_EN;    /* Clear D2P bit */+	if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))+		dunitCtrlHigh |= SDRAM__D2P_EN;++	return dunitCtrlHigh;+}++/*******************************************************************************+* sdramAddrCtrlRegCalc - Calculate sdram address control register+*+* DESCRIPTION: Calculate sdram address control register optimized value based+*			on the bank info parameters and the minCas.+*+* INPUT:+*	pBankInfo - sdram bank parameters+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram address control reg value.+*+*******************************************************************************/+static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)+{+	MV_U32 addrCtrl = 0;+	+	if (pBankInfoDIMM1->size)+	{+		switch (pBankInfoDIMM1->sdramWidth)+		{+			case 4:  /* memory is x4 */+				mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");+				return -1;+				break;+			case 8:  /* memory is x8 */+				addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);+				DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));+				break;+			case 16:+				addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);+				DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));+				break;+			default: /* memory width unsupported */+				mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");+				return -1;+		}+	}++	switch (pBankInfo->sdramWidth)+	{+		case 4:  /* memory is x4 */+			mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");+			return -1;+			break;+		case 8:  /* memory is x8 */+			addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);+			DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));+			break;+		case 16:+			addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);+			DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));+			break;+		default: /* memory width unsupported */+			mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");+			return -1;+	}++	/* Note that density is in MB units */+	switch (pBankInfo->deviceDensity) +	{+		case 256:                 /* 256 Mbit */+			DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));+			addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);+			break;+		case 512:                /* 512 Mbit */+			DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));+			addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);+			break;+		case 1024:                /* 1 Gbit */+			DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));+			addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);+			break;+		case 2048:                /* 2 Gbit */+			DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));+			addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);+			break;+		default:+			mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",+                       pBankInfo->deviceDensity);+			return -1;+        }++	if (pBankInfoDIMM1->size)+	{+		switch (pBankInfoDIMM1->deviceDensity) +		{+			case 256:                 /* 256 Mbit */+				DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));+				addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);+				break;+			case 512:                /* 512 Mbit */+				DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));+				addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);+				break;+			case 1024:                /* 1 Gbit */+				DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));+				addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);+				break;+			case 2048:                /* 2 Gbit */+				DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));+				addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);+				break;+			default:+				mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",+						   pBankInfoDIMM1->deviceDensity);+				return -1;+		}+	}+	/* SDRAM address control */+	DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));++	return addrCtrl;+}++/*******************************************************************************+* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register+*+* DESCRIPTION: +*       This function calculates sdram timing control low register +*       optimized value based on the bank info parameters and the minCas.+*+* INPUT:+*	    pBankInfo - sdram bank parameters+*	minCas	  - minimum CAS supported. +*       busClk    - Bus clock+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram timing control low reg value.+*+*******************************************************************************/+static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)+{+    MV_U32 tRp  = 0;+    MV_U32 tRrd = 0;+    MV_U32 tRcd = 0;+    MV_U32 tRas = 0;+    MV_U32 tWr  = 0;+    MV_U32 tWtr = 0;+    MV_U32 tRtp = 0;+    MV_U32 timeCtrlLow = 0;+	+    MV_U32 bankNum;+    +    busClk = busClk / 1000000;    /* In MHz */++    /* Scan all DRAM banks to find maximum timing values */+    for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+    {+        tRp  = MV_MAX(tRp,  pBankInfo[bankNum].minRowPrechargeTime);+        tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);+        tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);+        tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);+    }++    /* Extract timing (in ns) from SPD value. We ignore the tenth ns part.  */+    /* by shifting the data two bits right.                                 */+    tRp  = tRp  >> 2;    /* For example 0x50 -> 20ns                        */+    tRrd = tRrd >> 2;+    tRcd = tRcd >> 2;+	+    /* Extract clock cycles from time parameter. We need to round up        */+    tRp  = ((busClk * tRp)  / 1000) + (((busClk * tRp)  % 1000) ? 1 : 0);+    DB(mvOsPrintf("Dram  Timing Low: tRp = %d ", tRp));+    tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);+	/* JEDEC min reqeirments tRrd = 2 */+	if (tRrd < 2)+		tRrd = 2;+    DB(mvOsPrintf("tRrd = %d ", tRrd));+    tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);+    DB(mvOsPrintf("tRcd = %d ", tRcd));+    tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);+    DB(mvOsPrintf("tRas = %d ", tRas));++    /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2   */+	/* Scan all DRAM banks to find maximum timing values */+	for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+	    tWr  = MV_MAX(tWr,  pBankInfo[bankNum].minWriteRecoveryTime);+	    tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);+	    tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);+	}+	+	/* Extract timing (in ns) from SPD value. We ignore the tenth ns    */+	/* part by shifting the data two bits right.                        */+	tWr  = tWr  >> 2;    /* For example 0x50 -> 20ns                    */+	tWtr = tWtr >> 2;+	tRtp = tRtp >> 2;+	/* Extract clock cycles from time parameter. We need to round up    */+	tWr  = ((busClk * tWr)  / 1000) + (((busClk * tWr)  % 1000) ? 1 : 0);+	DB(mvOsPrintf("tWr = %d ", tWr));+	tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);+	/* JEDEC min reqeirments tWtr = 2 */+	if (tWtr < 2)+		tWtr = 2;+	DB(mvOsPrintf("tWtr = %d ", tWtr));+	tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);+	/* JEDEC min reqeirments tRtp = 2 */+	if (tRtp < 2)+	tRtp = 2;+	DB(mvOsPrintf("tRtp = %d ", tRtp));++	/* Note: value of 0 in register means one cycle, 1 means two and so on  */+	timeCtrlLow = (((tRp  - 1) << SDRAM_TRP_OFFS) |+		    ((tRrd - 1) << SDRAM_TRRD_OFFS) |+		    ((tRcd - 1) << SDRAM_TRCD_OFFS) |+		    (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|+		    ((tWr  - 1) << SDRAM_TWR_OFFS)  |+		    ((tWtr - 1) << SDRAM_TWTR_OFFS)	|+		    ((tRtp - 1) << SDRAM_TRTP_OFFS));+	+	/* Check extended tRas bit */+	if ((tRas - 1) & BIT4)+	    timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);++	return timeCtrlLow;+}++/*******************************************************************************+* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register+*+* DESCRIPTION: +*       This function calculates sdram timing control high register +*       optimized value based on the bank info parameters and the bus clock.+*+* INPUT:+*	    pBankInfo - sdram bank parameters+*       busClk    - Bus clock+*+* OUTPUT:+*       None+*+* RETURN:+*       sdram timing control high reg value.+*+*******************************************************************************/+static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)+{+	MV_U32 tRfc;+	MV_U32 timingHigh;+	MV_U32 timeNs = 0;+	MV_U32 bankNum;+	+	busClk = busClk / 1000000;    /* In MHz */++	/* Set DDR timing high register static configuration bits */+	timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);+	+	/* Set DDR timing high register default value */+	timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;  +	+	/* Clear tRfc field */+	timingHigh &= ~SDRAM_TRFC_MASK;++	/* Scan all DRAM banks to find maximum timing values */+	for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		timeNs = MV_MAX(timeNs,  pBankInfo[bankNum].minRefreshToActiveCmd);+		DB(mvOsPrintf("Dram:  Timing High: minRefreshToActiveCmd = %d\n", +				pBankInfo[bankNum].minRefreshToActiveCmd));+	}+	if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)+    {+        timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;+    }++	tRfc = ((busClk * timeNs)  / 1000) + (((busClk * timeNs)  % 1000) ? 1 : 0);+	/* Note: value of 0 in register means one cycle, 1 means two and so on  */+	DB(mvOsPrintf("Dram:  Timing High: tRfc = %d\n", tRfc));+	timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);+	DB(mvOsPrintf("Dram:  Timing High: tRfc = %d\n", tRfc));+	+	/* SDRAM timing high */+	DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));++	return timingHigh;+}+/*******************************************************************************+* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.+*+* DESCRIPTION: +*       This function config DDR2 On Die Termination (ODT) registers.+*	+* INPUT:+*		pBankInfo - bank info parameters.+*+* OUTPUT:+*       None+*+* RETURN:+*       None+*******************************************************************************/+static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)+{+	MV_U32 populateBanks = 0;+	MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;+	int bankNum;+	+	/* Represent the populate banks in binary form */+	for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)+	{+		if (0 != pBankInfo[bankNum].size)+		{+				populateBanks |= (1 << bankNum);+			}+		}+	+	switch(populateBanks)+	{+		case(BANK_PRESENT_CS0):+		case(BANK_PRESENT_CS0_CS1):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;+			break;+		case(BANK_PRESENT_CS0_CS2):+		case(BANK_PRESENT_CS0_CS1_CS2):+		case(BANK_PRESENT_CS0_CS2_CS3):+		case(BANK_PRESENT_CS0_CS2_CS3_CS4):+			odtCtrlLow   = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;+			odtCtrlHigh  = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;+			dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;+			break;+		default:+			DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));+			return;+	}+ 	/* DDR2 SDRAM ODT ctrl low  */+	DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));+	MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);++ 	/* DDR2 SDRAM ODT ctrl high  */+	DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));+	MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);++	/* DDR2 DUNIT ODT ctrl  */+	if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||+		(mvCtrlModelGet() == MV_76100_DEV_ID) ||+		(mvCtrlModelGet() == MV_78100_DEV_ID) ||+		(mvCtrlModelGet() == MV_78200_DEV_ID) )+		dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */++	DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));+	MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);+	return;+}+/*******************************************************************************+* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.+*+* DESCRIPTION: +*       This function config DDR2 DRAM Timing low registers.+*	+* INPUT:+*	minCas	  - minimum CAS supported. +*+* OUTPUT:+*       None+*+* RETURN:+*       DDR2 sdram timing low reg value.+*******************************************************************************/+static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)+{+	MV_U8 cl = -1;+	MV_U32 ddr2TimeLoReg;++	/* read and clear the feilds we are going to set */+	ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);+	ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK	| +			   SD2TLR_TODT_OFF_RD_MASK	| +			   SD2TLR_TODT_ON_CTRL_RD_MASK	|+			   SD2TLR_TODT_OFF_CTRL_RD_MASK);++	if( minCas == DDR2_CL_3 )+	{+		cl = 3;+	}+	else if( minCas == DDR2_CL_4 )+	{+		cl = 4;+	}+	else if( minCas == DDR2_CL_5 )+	{+		cl = 5;+	}+	else if( minCas == DDR2_CL_6 )+	{+		cl = 6;+	}+	else+	{+		DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",+				minCas));+		cl = 4;+	}++	ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);+	ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);+	ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);+	ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);++	/* DDR2 SDRAM timing low */+	DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));++	return ddr2TimeLoReg;+}++/*******************************************************************************+* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.+*+* DESCRIPTION: +*       This function config DDR2 DRAM Timing high registers.+*	+* INPUT:+*	minCas	  - minimum CAS supported. +*+* OUTPUT:+*       None+*+* RETURN:+*       DDR2 sdram timing high reg value.+*******************************************************************************/+static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)+{+	MV_U8 cl = -1;+	MV_U32 ddr2TimeHiReg;++	/* read and clear the feilds we are going to set */+	ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);+	ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK	|+			   SD2THR_TODT_OFF_WR_MASK	|+			   SD2THR_TODT_ON_CTRL_WR_MASK	|+			   SD2THR_TODT_OFF_CTRL_WR_MASK);++	if( minCas == DDR2_CL_3 )+	{+		cl = 3;+	}+	else if( minCas == DDR2_CL_4 )+	{+		cl = 4;+	}+	else if( minCas == DDR2_CL_5 )+	{+		cl = 5;+	}+	else if( minCas == DDR2_CL_6 )+	{+		cl = 6;+	}+	else+	{+		mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n", +				minCas);+		cl = 4;+	}++	ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);+	ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);+	ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);+	ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);++	/* DDR2 SDRAM timin high  */+	DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));++	return ddr2TimeHiReg;+}+#endif++/*******************************************************************************+* mvDramIfCalGet - Get CAS Latency+*+* DESCRIPTION: +*       This function get the CAS Latency.+*+* INPUT:+*       None+*+* OUTPUT:+*       None+*+* RETURN:+*       CAS latency times 10 (to avoid using floating point).+*+*******************************************************************************/+MV_U32 mvDramIfCalGet(void)+{+	MV_U32 sdramCasLat, casLatMask;+	+    casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);++    switch (casLatMask)+    {+        case SDRAM_DDR2_CL_3: +            sdramCasLat = 30;+            break;+        case SDRAM_DDR2_CL_4: +            sdramCasLat = 40;+            break;+        case SDRAM_DDR2_CL_5: +            sdramCasLat = 50;+            break;+        case SDRAM_DDR2_CL_6: +            sdramCasLat = 60;+            break;+        default:+            mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");+            return -1;+    }                                  +    +    return sdramCasLat;+}+++/*******************************************************************************+* mvDramIfSelfRefreshSet - Put the dram in self refresh mode - +*+* DESCRIPTION: +*               add support in power management.+*                          +*+* INPUT:+*       None+*+* OUTPUT:+*       None+*+* RETURN:+*       None+*+*******************************************************************************/++MV_VOID mvDramIfSelfRefreshSet()+{+    MV_U32 operReg;++      operReg =  MV_REG_READ(SDRAM_OPERATION_REG);+      MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);+      /* Read until register is reset to 0 */+      while(MV_REG_READ(SDRAM_OPERATION_REG));+}+/*******************************************************************************+* mvDramIfDimGetSPDversion - return DIMM SPD version.+*+* DESCRIPTION:+*		This function prints the DRAM controller information.+*+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*		None.+*+*******************************************************************************/+static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)+{+	MV_DIMM_INFO dimmInfo;+	if (bankNum >= MV_DRAM_MAX_CS )+	{+		DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n")); +		return ;+	}+	memset(&dimmInfo,0,sizeof(dimmInfo));+	if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))+	{+		DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));+		return ;+	}+	*pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;+	*pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;+}+/*******************************************************************************+* mvDramIfShow - Show DRAM controller information.+*+* DESCRIPTION:+*		This function prints the DRAM controller information.+*+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*		None.+*+*******************************************************************************/+void mvDramIfShow(void)+{+    int i, sdramCasLat, sdramCsSize;+	MV_U32 Major=0, Minor=0;+    +    mvOsOutput("DRAM Controller info:\n");+    +    mvOsOutput("Total DRAM ");+    mvSizePrint(mvDramIfSizeGet());+    mvOsOutput("\n");++	for(i = 0; i < MV_DRAM_MAX_CS; i++)+	{ +        sdramCsSize = mvDramIfBankSizeGet(i);+        if (sdramCsSize)+        {+			if (0 == (i & 1))+			{+				mvDramIfDimGetSPDversion(&Major, &Minor,i);+				mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);+			}+            mvOsOutput("\tDRAM CS[%d] ", i);+            mvSizePrint(sdramCsSize);+            mvOsOutput("\n");+        }+    }+    sdramCasLat = mvDramIfCalGet();++    if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)+    {+        mvOsOutput("ECC enabled, ");+    }+    else+    {+        mvOsOutput("ECC Disabled, ");+    }+    +    if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)+    {+        mvOsOutput("Registered DIMM\n");+    }+    else+    {+        mvOsOutput("Non registered DIMM\n");+    }++    mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);+}+/*******************************************************************************+* mvDramIfGetFirstCS - find the  DRAM bank on the lower address+* +*+* DESCRIPTION:+*       This function return the fisrt CS on address 0+*+* INPUT:+*		None.+*+* OUTPUT:+*		None.+*+* RETURN:+*       SDRAM_CS0 or SDRAM_CS2+*+*******************************************************************************/+MV_U32 mvDramIfGetFirstCS(void)+{+	MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];++	if (DRAM_CS_Order[0] == N_A)+	{+		mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);+#ifdef MV_INCLUDE_SDRAM_CS2+		mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);+#endif +		+#ifdef MV_INCLUDE_SDRAM_CS2+		if (bankInfo[SDRAM_CS0].size <  bankInfo[SDRAM_CS2].size)+		{+			DRAM_CS_Order[0] = SDRAM_CS2;+			DRAM_CS_Order[1] = SDRAM_CS3;+			DRAM_CS_Order[2] = SDRAM_CS0;+			DRAM_CS_Order[3] = SDRAM_CS1;++			return SDRAM_CS2;+		}+#endif+		DRAM_CS_Order[0] = SDRAM_CS0;+		DRAM_CS_Order[1] = SDRAM_CS1;+#ifdef MV_INCLUDE_SDRAM_CS2+		DRAM_CS_Order[2] = SDRAM_CS2;+		DRAM_CS_Order[3] = SDRAM_CS3;+#endif	+		return SDRAM_CS0;+	}+	return DRAM_CS_Order[0];+}+/*******************************************************************************+* mvDramIfGetCSorder - +* +*+* DESCRIPTION:+*       This function return the fisrt CS on address 0+*+* INPUT:+*		CS number.+*+* OUTPUT:+*		CS order.+*+* RETURN:+*       SDRAM_CS0 or SDRAM_CS2+* +* NOTE: mvDramIfGetFirstCS must be caled before this subroutine+*******************************************************************************/+MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )+{+	return DRAM_CS_Order[csOrder];+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h	2010-11-09 20:28:10.852495382 +0100@@ -0,0 +1,157 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvDramIfConfigh+#define __INCmvDramIfConfigh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* includes */++/* defines  */++/* registers defaults values */++#define SDRAM_CONFIG_DV 	(SDRAM_SRMODE_DRAM | BIT25 | BIT30)++#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV			\+		(SDRAM_SRCLK_KEPT		|	\+		 SDRAM_CLK1DRV_NORMAL		|	\+		 (BIT28 | BIT29))++#define SDRAM_ADDR_CTRL_DV	    2+		+#define SDRAM_TIMING_CTRL_LOW_REG_DV 	\+		((0x2 << SDRAM_TRCD_OFFS) | 	\+		 (0x2 << SDRAM_TRP_OFFS)  | 	\+		 (0x1 << SDRAM_TWR_OFFS)  | 	\+		 (0x0 << SDRAM_TWTR_OFFS) | 	\+		 (0x5 << SDRAM_TRAS_OFFS) | 	\+		 (0x1 << SDRAM_TRRD_OFFS))++/* Note: value of 0 in register means one cycle, 1 means two and so on  */+#define SDRAM_TIMING_CTRL_HIGH_REG_DV 	\+		((0x0 << SDRAM_TR2R_OFFS)	|	\+		 (0x0 << SDRAM_TR2W_W2R_OFFS)	|	\+		 (0x1 << SDRAM_TW2W_OFFS))++#define SDRAM_OPEN_PAGES_CTRL_REG_DV 	SDRAM_OPEN_PAGE_EN	++/* Presence	     Ctrl Low    Ctrl High  Dunit Ctrl   Ext Mode     */+/* CS0              0x84210000  0x00000000  0x0000780F  0x00000440    */+/* CS0+CS1          0x84210000  0x00000000  0x0000780F  0x00000440    */+/* CS0+CS2          0x030C030C  0x00000000  0x0000740F  0x00000404    */+/* CS0+CS1+CS2      0x030C030C  0x00000000  0x0000740F  0x00000404    */+/* CS0+CS2+CS3      0x030C030C  0x00000000  0x0000740F  0x00000404    */+/* CS0+CS1+CS2+CS3  0x030C030C  0x00000000  0x0000740F  0x00000404    */++#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV		0x84210000+#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV		0x00000000+#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV		0x0000E80F+#ifdef MV78XX0+#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV		0x00000040+#else+#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV		0x00000440+#endif++#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV	0x030C030C+#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV	0x00000000+#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV	0x0000F40F+#ifdef MV78XX0+#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV	0x00000004+#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV	0x00000044+#else+#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV	0x00000404+#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV	0x00000444+#endif++/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */+#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV	\+		(3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)+		+#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV		\+		(3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)++/* DDR SDRAM Mode Register default value */+#define DDR2_MODE_REG_DV		(SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)+/* DDR SDRAM Timing parameter default values */+#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT  	0x33136552+#define SDRAM_TRFC_DEFAULT_VALUE		0x34+#define SDRAM_TRFC_DEFAULT		SDRAM_TRFC_DEFAULT_VALUE+#define SDRAM_TW2W_DEFALT		(0x1 << SDRAM_TW2W_OFFS)++#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT  (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)++#define SDRAM_FTDLL_REG_DEFAULT_LEFT  		0x88C800+#define SDRAM_FTDLL_REG_DEFAULT_RIGHT  		0x88C800+#define SDRAM_FTDLL_REG_DEFAULT_UP  		0x88C800++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvDramIfh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h	2010-11-09 20:28:10.882495421 +0100@@ -0,0 +1,172 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvDramIfh+#define __INCmvDramIfh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* includes */+#include "ddr2/mvDramIfRegs.h"+#include "ddr2/mvDramIfConfig.h"+#include "ctrlEnv/mvCtrlEnvLib.h"++/* defines  */+/* DRAM Timing parameters */+#define SDRAM_TWR                    15  /* ns tWr */+#define SDRAM_TRFC_64_512M_AT_200MHZ 70  /* ns tRfc for dens 64-512 @ 200MHz */+#define SDRAM_TRFC_64_512M           75  /* ns tRfc for dens 64-512          */+#define SDRAM_TRFC_1G                120 /* ns tRfc for dens 1GB             */+#define SDRAM_TR2R_CYC               1   /* cycle for tR2r                   */++#define CAL_AUTO_DETECT     0   /* Do not force CAS latancy (mvDramIfDetect) */+#define ECC_DISABLE         1   /* Force ECC to Disable                      */+#define ECC_ENABLE          0   /* Force ECC to ENABLE                       */+/* typedefs */++/* enumeration for memory types */+typedef enum _mvMemoryType+{+    MEM_TYPE_SDRAM,+    MEM_TYPE_DDR1,+    MEM_TYPE_DDR2+}MV_MEMORY_TYPE;++/* enumeration for DDR2 supported CAS Latencies */+typedef enum _mvDimmDdr2Cas+{+    DDR2_CL_3    = 0x08, +    DDR2_CL_4    = 0x10, +    DDR2_CL_5    = 0x20, +    DDR2_CL_6    = 0x40, +    DDR2_CL_FAULT+} MV_DIMM_DDR2_CAS;+++typedef struct _mvDramBankInfo+{+    MV_MEMORY_TYPE  memoryType; 	/* DDR1, DDR2 or SDRAM */++    /* DIMM dimensions */+    MV_U32  numOfRowAddr;+    MV_U32  numOfColAddr;+    MV_U32  dataWidth;+    MV_U32  errorCheckType;             /* ECC , PARITY..*/+    MV_U32  sdramWidth;                 /* 4,8,16 or 32 */+    MV_U32  errorCheckDataWidth;        /* 0 - no, 1 - Yes */+    MV_U32  burstLengthSupported;+    MV_U32  numOfBanksOnEachDevice;+    MV_U32  suportedCasLatencies;+    MV_U32  refreshInterval;++    /* DIMM timing parameters */+    MV_U32  minCycleTimeAtMaxCasLatPs;	+    MV_U32  minCycleTimeAtMaxCasLatMinus1Ps;+    MV_U32  minCycleTimeAtMaxCasLatMinus2Ps;+    MV_U32  minRowPrechargeTime;+    MV_U32  minRowActiveToRowActive;+    MV_U32  minRasToCasDelay;+    MV_U32  minRasPulseWidth;+    MV_U32  minWriteRecoveryTime;   /* DDR2 only */+    MV_U32  minWriteToReadCmdDelay; /* DDR2 only */+    MV_U32  minReadToPrechCmdDelay; /* DDR2 only */+    MV_U32  minRefreshToActiveCmd;  /* DDR2 only */+                      +    /* Parameters calculated from the extracted DIMM information */+    MV_U32  size;+    MV_U32  deviceDensity;           	/* 16,64,128,256 or 512 Mbit */+    MV_U32  numberOfDevices;++    /* DIMM attributes (MV_TRUE for yes) */+    MV_BOOL registeredAddrAndControlInputs;+    MV_BOOL registeredDQMBinputs;+     +}MV_DRAM_BANK_INFO;++#include "ddr2/spd/mvSpd.h"++/* mvDramIf.h API list */+MV_VOID   mvDramIfBasicAsmInit(MV_VOID);+MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);+MV_VOID   _mvDramIfConfig(int entryNum);++MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);+MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);+MV_U32 mvDramIfSizeGet(MV_VOID);+MV_U32 mvDramIfCalGet(void);+MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);+MV_VOID mvDramIfSelfRefreshSet(void);+void mvDramIfShow(void);+MV_U32 mvDramIfGetFirstCS(void);+MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );+MV_U32 mvDramCsSizeGet(MV_U32 csNum);++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvDramIfh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h	2010-11-09 20:28:10.921244571 +0100@@ -0,0 +1,423 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDramIfRegsh+#define __INCmvDramIfRegsh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* DDR SDRAM Controller Address Decode Registers */+ /* SDRAM CSn Base Address Register (SCBAR) */+#define SDRAM_BASE_ADDR_REG(cpu,csNum)	(0x1500 + ((csNum) * 8) + ((cpu) * 0x70))+#define SCBAR_BASE_OFFS			16 +#define SCBAR_BASE_MASK			(0xffff << SCBAR_BASE_OFFS)+#define SCBAR_BASE_ALIGNMENT		0x10000 ++/* SDRAM CSn Size Register (SCSR) */		  +#define SDRAM_SIZE_REG(cpu,csNum)	(0x1504 + ((csNum) * 8) + ((cpu) * 0x70)) +#define SCSR_SIZE_OFFS			24+#define SCSR_SIZE_MASK			(0xff << SCSR_SIZE_OFFS)+#define SCSR_SIZE_ALIGNMENT		0x1000000+#define SCSR_WIN_EN			BIT0++/* configuration register */+#define SDRAM_CONFIG_REG   		(DRAM_BASE + 0x1400)+#define SDRAM_REFRESH_OFFS 		0+#define SDRAM_REFRESH_MAX  		0x3FFF+#define SDRAM_REFRESH_MASK 		(SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)+#define SDRAM_DWIDTH_OFFS       	15+#define SDRAM_DWIDTH_MASK       	(1 << SDRAM_DWIDTH_OFFS)+#define SDRAM_DWIDTH_32BIT      	(0 << SDRAM_DWIDTH_OFFS)+#define SDRAM_DWIDTH_64BIT      	(1 << SDRAM_DWIDTH_OFFS)+#define SDRAM_REGISTERED   		(1 << 17)+#define SDRAM_ECC_OFFS    		18+#define SDRAM_ECC_MASK    		(1 << SDRAM_ECC_OFFS)+#define SDRAM_ECC_DIS     		(0 << SDRAM_ECC_OFFS)+#define SDRAM_ECC_EN        		(1 << SDRAM_ECC_OFFS)+#define SDRAM_IERR_OFFS    		19+#define SDRAM_IERR_MASK    		(1 << SDRAM_IERR_OFFS)+#define SDRAM_IERR_REPORTE     		(0 << SDRAM_IERR_OFFS)+#define SDRAM_IERR_IGNORE      		(1 << SDRAM_IERR_OFFS)+#define SDRAM_SRMODE_OFFS       	24+#define SDRAM_SRMODE_MASK       	(1 << SDRAM_SRMODE_OFFS)+#define SDRAM_SRMODE_POWER      	(0 << SDRAM_SRMODE_OFFS)+#define SDRAM_SRMODE_DRAM       	(1 << SDRAM_SRMODE_OFFS)++/* dunit control low register */+#define SDRAM_DUNIT_CTRL_REG  		(DRAM_BASE + 0x1404)+#define SDRAM_2T_OFFS			4+#define SDRAM_2T_MASK			(1 << SDRAM_2T_OFFS)+#define SDRAM_2T_MODE			(1 << SDRAM_2T_OFFS)++#define SDRAM_SRCLK_OFFS		5+#define SDRAM_SRCLK_MASK		(1 << SDRAM_SRCLK_OFFS)+#define SDRAM_SRCLK_KEPT		(0 << SDRAM_SRCLK_OFFS)+#define SDRAM_SRCLK_GATED		(1 << SDRAM_SRCLK_OFFS)+#define SDRAM_CTRL_POS_OFFS	   	6+#define SDRAM_CTRL_POS_MASK		(1 << SDRAM_CTRL_POS_OFFS)+#define SDRAM_CTRL_POS_FALL	   	(0 << SDRAM_CTRL_POS_OFFS)+#define SDRAM_CTRL_POS_RISE	   	(1 << SDRAM_CTRL_POS_OFFS)+#define SDRAM_CLK1DRV_OFFS      	12+#define SDRAM_CLK1DRV_MASK      	(1 << SDRAM_CLK1DRV_OFFS)+#define SDRAM_CLK1DRV_HIGH_Z    	(0 << SDRAM_CLK1DRV_OFFS)+#define SDRAM_CLK1DRV_NORMAL    	(1 << SDRAM_CLK1DRV_OFFS)+#define SDRAM_CLK2DRV_OFFS      	13+#define SDRAM_CLK2DRV_MASK      	(1 << SDRAM_CLK2DRV_OFFS)+#define SDRAM_CLK2DRV_HIGH_Z    	(0 << SDRAM_CLK2DRV_OFFS)+#define SDRAM_CLK2DRV_NORMAL    	(1 << SDRAM_CLK2DRV_OFFS)+#define SDRAM_SB_OUT_DEL_OFFS 		20+#define SDRAM_SB_OUT_DEL_MAX 		0xf+#define SDRAM_SB_OUT_MASK 		(SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)+#define SDRAM_SB_IN_DEL_OFFS 		24+#define SDRAM_SB_IN_DEL_MAX 		0xf+#define SDRAM_SB_IN_MASK 		(SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)++/* dunit control hight register */+#define SDRAM_DUNIT_CTRL_HI_REG  	(DRAM_BASE + 0x1424)+#define SDRAM__D2P_OFFS			7+#define SDRAM__D2P_EN			(1 << SDRAM__D2P_OFFS)+#define SDRAM__P2D_OFFS			8+#define SDRAM__P2D_EN			(1 << SDRAM__P2D_OFFS)+#define SDRAM__ADD_HALF_FCC_OFFS	9+#define SDRAM__ADD_HALF_FCC_EN		(1 << SDRAM__ADD_HALF_FCC_OFFS)+#define SDRAM__PUP_ZERO_SKEW_OFFS	10+#define SDRAM__PUP_ZERO_SKEW_EN		(1 << SDRAM__PUP_ZERO_SKEW_OFFS)+#define SDRAM__WR_MESH_DELAY_OFFS	11+#define SDRAM__WR_MESH_DELAY_EN		(1 << SDRAM__WR_MESH_DELAY_OFFS)++/* sdram timing control low register */+#define SDRAM_TIMING_CTRL_LOW_REG	(DRAM_BASE + 0x1408)+#define SDRAM_TRCD_OFFS 		4+#define SDRAM_TRCD_MASK 		(0xF << SDRAM_TRCD_OFFS)+#define SDRAM_TRP_OFFS 			8+#define SDRAM_TRP_MASK 			(0xF << SDRAM_TRP_OFFS)+#define SDRAM_TWR_OFFS 			12+#define SDRAM_TWR_MASK 			(0xF << SDRAM_TWR_OFFS)+#define SDRAM_TWTR_OFFS 		16+#define SDRAM_TWTR_MASK 		(0xF << SDRAM_TWTR_OFFS)+#define SDRAM_TRAS_OFFS 		0+#define SDRAM_TRAS_MASK 		(0xF << SDRAM_TRAS_OFFS)+#define SDRAM_EXT_TRAS_OFFS 		20+#define SDRAM_EXT_TRAS_MASK 		(0x1 << SDRAM_EXT_TRAS_OFFS)+#define SDRAM_TRRD_OFFS 		24+#define SDRAM_TRRD_MASK 		(0xF << SDRAM_TRRD_OFFS)+#define SDRAM_TRTP_OFFS			28+#define SDRAM_TRTP_MASK			(0xF << SDRAM_TRTP_OFFS)+#define SDRAM_TRTP_DDR1 		(0x1 << SDRAM_TRTP_OFFS)++/* sdram timing control high register */+#define SDRAM_TIMING_CTRL_HIGH_REG	(DRAM_BASE + 0x140c)+#define SDRAM_TRFC_OFFS 		0+#define SDRAM_TRFC_MASK 		(0x3F << SDRAM_TRFC_OFFS)+#define SDRAM_TR2R_OFFS 		7+#define SDRAM_TR2R_MASK 		(0x3 << SDRAM_TR2R_OFFS)+#define SDRAM_TR2W_W2R_OFFS		9+#define SDRAM_TR2W_W2R_MASK		(0x3 << SDRAM_TR2W_W2R_OFFS)+#define SDRAM_TW2W_OFFS			11+#define SDRAM_TW2W_MASK			(0x3 << SDRAM_TW2W_OFFS)++/* sdram DDR2 timing low register (SD2TLR) */+#define SDRAM_DDR2_TIMING_LO_REG	(DRAM_BASE + 0x1428)+#define SD2TLR_TODT_ON_RD_OFFS		4+#define SD2TLR_TODT_ON_RD_MASK		(0xF << SD2TLR_TODT_ON_RD_OFFS)+#define SD2TLR_TODT_OFF_RD_OFFS		8+#define SD2TLR_TODT_OFF_RD_MASK		(0xF << SD2TLR_TODT_OFF_RD_OFFS)+#define SD2TLR_TODT_ON_CTRL_RD_OFFS	12+#define SD2TLR_TODT_ON_CTRL_RD_MASK	(0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)+#define SD2TLR_TODT_OFF_CTRL_RD_OFFS	16+#define SD2TLR_TODT_OFF_CTRL_RD_MASK	(0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)++/* sdram DDR2 timing high register (SD2TLR) */+#define SDRAM_DDR2_TIMING_HI_REG	(DRAM_BASE + 0x147C)+#define SD2THR_TODT_ON_WR_OFFS		0+#define SD2THR_TODT_ON_WR_MASK		(0xF << SD2THR_TODT_ON_WR_OFFS)+#define SD2THR_TODT_OFF_WR_OFFS		4+#define SD2THR_TODT_OFF_WR_MASK		(0xF << SD2THR_TODT_OFF_WR_OFFS)+#define SD2THR_TODT_ON_CTRL_WR_OFFS	8+#define SD2THR_TODT_ON_CTRL_WR_MASK	(0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)+#define SD2THR_TODT_OFF_CTRL_WR_OFFS	12+#define SD2THR_TODT_OFF_CTRL_WR_MASK	(0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)++/* address control register */+#define SDRAM_ADDR_CTRL_REG		(DRAM_BASE + 0x1410)+#define SDRAM_ADDRSEL_OFFS(cs)		(4 * (cs))+#define SDRAM_ADDRSEL_MASK(cs)		(0x3 << SDRAM_ADDRSEL_OFFS(cs))+#define SDRAM_ADDRSEL_X8(cs)		(0x0 << SDRAM_ADDRSEL_OFFS(cs))+#define SDRAM_ADDRSEL_X16(cs)		(0x1 << SDRAM_ADDRSEL_OFFS(cs))+#define SDRAM_DSIZE_OFFS(cs)   	    	(2 + 4 * (cs))+#define SDRAM_DSIZE_MASK(cs)   	    	(0x3 << SDRAM_DSIZE_OFFS(cs))+#define SDRAM_DSIZE_256Mb(cs) 	    	(0x1 << SDRAM_DSIZE_OFFS(cs))+#define SDRAM_DSIZE_512Mb(cs)  	    	(0x2 << SDRAM_DSIZE_OFFS(cs))+#define SDRAM_DSIZE_1Gb(cs)  	    	(0x3 << SDRAM_DSIZE_OFFS(cs))+#define SDRAM_DSIZE_2Gb(cs)  	    	(0x0 << SDRAM_DSIZE_OFFS(cs))++/* SDRAM Open Pages Control registers */+#define SDRAM_OPEN_PAGE_CTRL_REG	(DRAM_BASE + 0x1414)+#define SDRAM_OPEN_PAGE_EN			(0 << 0)+#define SDRAM_OPEN_PAGE_DIS			(1 << 0)++/* sdram opertion register */+#define SDRAM_OPERATION_REG 		(DRAM_BASE + 0x1418)+#define SDRAM_CMD_OFFS  			0+#define SDRAM_CMD_MASK   			(0xF << SDRAM_CMD_OFFS)+#define SDRAM_CMD_NORMAL 			(0x0 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_PRECHARGE_ALL 	(0x1 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_REFRESH_ALL 		(0x2 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_REG_SET_CMD 		(0x3 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_EXT_MODE_SET 		(0x4 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_NOP 				(0x5 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_SLF_RFRSH 		(0x7 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_EMRS2_CMD  		(0x8 << SDRAM_CMD_OFFS)+#define SDRAM_CMD_EMRS3_CMD  		(0x9 << SDRAM_CMD_OFFS)++/* sdram mode register */+#define SDRAM_MODE_REG 				(DRAM_BASE + 0x141c)+#define SDRAM_BURST_LEN_OFFS 		0+#define SDRAM_BURST_LEN_MASK 		(0x7 << SDRAM_BURST_LEN_OFFS)+#define SDRAM_BURST_LEN_4    		(0x2 << SDRAM_BURST_LEN_OFFS)+#define SDRAM_CL_OFFS   			4+#define SDRAM_CL_MASK   			(0x7 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_3      		(0x3 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_4      		(0x4 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_5    		    (0x5 << SDRAM_CL_OFFS)+#define SDRAM_DDR2_CL_6    		    (0x6 << SDRAM_CL_OFFS)++#define SDRAM_TM_OFFS           	7+#define SDRAM_TM_MASK           	(1 << SDRAM_TM_OFFS)+#define SDRAM_TM_NORMAL         	(0 << SDRAM_TM_OFFS)+#define SDRAM_TM_TEST_MODE      	(1 << SDRAM_TM_OFFS)+#define SDRAM_DLL_OFFS         		8+#define SDRAM_DLL_MASK          	(1 << SDRAM_DLL_OFFS)+#define SDRAM_DLL_NORMAL        	(0 << SDRAM_DLL_OFFS)+#define SDRAM_DLL_RESET 			(1 << SDRAM_DLL_OFFS)+#define SDRAM_WR_OFFS				9+#define SDRAM_WR_MAX				7+#define SDRAM_WR_MASK				(SDRAM_WR_MAX << SDRAM_WR_OFFS)+#define SDRAM_WR_2_CYC				(1 << SDRAM_WR_OFFS)+#define SDRAM_WR_3_CYC				(2 << SDRAM_WR_OFFS)+#define SDRAM_WR_4_CYC				(3 << SDRAM_WR_OFFS)+#define SDRAM_WR_5_CYC				(4 << SDRAM_WR_OFFS)+#define SDRAM_WR_6_CYC				(5 << SDRAM_WR_OFFS)+#define SDRAM_PD_OFFS				12+#define SDRAM_PD_MASK				(1 << SDRAM_PD_OFFS) +#define SDRAM_PD_FAST_EXIT			(0 << SDRAM_PD_OFFS) +#define SDRAM_PD_SLOW_EXIT			(1 << SDRAM_PD_OFFS) ++/* DDR SDRAM Extended Mode register (DSEMR) */+#define SDRAM_EXTENDED_MODE_REG		(DRAM_BASE + 0x1420)+#define DSEMR_DLL_ENABLE			0+#define DSEMR_DLL_DISABLE			1+#define DSEMR_DS_OFFS				1+#define DSEMR_DS_MASK				(1 << DSEMR_DS_OFFS)+#define DSEMR_DS_NORMAL				(0 << DSEMR_DS_OFFS)+#define DSEMR_DS_REDUCED			(1 << DSEMR_DS_OFFS)+#define DSEMR_QOFF_OUTPUT_BUFF_EN	(0 << 12)+#define DSEMR_RTT0_OFFS				2+#define DSEMR_RTT1_OFFS				6+#define DSEMR_RTT_ODT_DISABLE		((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))+#define DSEMR_RTT_ODT_75_OHM		((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))+#define DSEMR_RTT_ODT_150_OHM		((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))+#define DSEMR_RTT_ODT_50_OHM		((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))+#define DSEMR_DQS_OFFS				10+#define DSEMR_DQS_MASK				(1 << DSEMR_DQS_OFFS)+#define DSEMR_DQS_DIFFERENTIAL		(0 << DSEMR_DQS_OFFS)+#define DSEMR_DQS_SINGLE_ENDED		(1 << DSEMR_DQS_OFFS)+#define DSEMR_RDQS_ENABLE			(1 << 11)+#define DSEMR_QOFF_OUTPUT_BUFF_EN	(0 << 12)+#define DSEMR_QOFF_OUTPUT_BUFF_DIS	(1 << 12)++/* DDR SDRAM Operation Control Register */+#define SDRAM_OPERATION_CTRL_REG	(DRAM_BASE + 0x142c)++/* Dunit FTDLL Configuration Register */+#define SDRAM_FTDLL_CONFIG_LEFT_REG		(DRAM_BASE + 0x1484)+#define SDRAM_FTDLL_CONFIG_RIGHT_REG		(DRAM_BASE + 0x161C)+#define SDRAM_FTDLL_CONFIG_UP_REG		(DRAM_BASE + 0x1620)+  +/* Pads Calibration register */+#define SDRAM_ADDR_CTRL_PADS_CAL_REG	(DRAM_BASE + 0x14c0)+#define SDRAM_DATA_PADS_CAL_REG		    (DRAM_BASE + 0x14c4)+#define SDRAM_DRVN_OFFS 			0+#define SDRAM_DRVN_MASK 			(0x3F << SDRAM_DRVN_OFFS)+#define SDRAM_DRVP_OFFS 			6+#define SDRAM_DRVP_MASK 			(0x3F << SDRAM_DRVP_OFFS)+#define SDRAM_PRE_DRIVER_STRENGTH_OFFS		12+#define SDRAM_PRE_DRIVER_STRENGTH_MASK		(3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)+#define SDRAM_TUNE_EN   		BIT16+#define SDRAM_LOCKN_OFFS 			17+#define SDRAM_LOCKN_MAKS 			(0x3F << SDRAM_LOCKN_OFFS)+#define SDRAM_LOCKP_OFFS 			23+#define SDRAM_LOCKP_MAKS 			(0x3F << SDRAM_LOCKP_OFFS)+#define SDRAM_WR_EN     			(1 << 31)++/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */+#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)+#define DSOCLR_ODT_RD_OFFS(odtNum)  (odtNum * 4)+#define DSOCLR_ODT_RD_MASK(odtNum)  (0xf << DSOCLR_ODT_RD_OFFS(odtNum))+#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))+#define DSOCLR_ODT_WR_OFFS(odtNum)  (16 + (odtNum * 4))+#define DSOCLR_ODT_WR_MASK(odtNum)  (0xf << DSOCLR_ODT_WR_OFFS(odtNum))+#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))++/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */+#define DDR2_SDRAM_ODT_CTRL_HIGH_REG    	(DRAM_BASE + 0x1498)+/* Optional control values to DSOCHR_ODT_EN macro */+#define DDR2_ODT_CTRL_DUNIT         0+#define DDR2_ODT_CTRL_NEVER         1+#define DDR2_ODT_CTRL_ALWAYS        3+#define DSOCHR_ODT_EN_OFFS(odtNum)  (odtNum * 2)+#define DSOCHR_ODT_EN_MASK(odtNum)  (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))+#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))++/* DDR2 Dunit ODT Control Register (DDOCR)*/+#define DDR2_DUNIT_ODT_CONTROL_REG  (DRAM_BASE + 0x149c)+#define DDOCR_ODT_RD_OFFS          	0+#define DDOCR_ODT_RD_MASK           (0xf << DDOCR_ODT_RD_OFFS)+#define DDOCR_ODT_RD(bank)          ((1 << bank) << DDOCR_ODT_RD_OFFS)+#define DDOCR_ODT_WR_OFFS           4+#define DDOCR_ODT_WR_MASK           (0xf << DDOCR_ODT_WR_OFFS)+#define DDOCR_ODT_WR(bank)          ((1 << bank) << DDOCR_ODT_WR_OFFS)+#define DSOCR_ODT_EN_OFFS           8+#define DSOCR_ODT_EN_MASK           (0x3 << DSOCR_ODT_EN_OFFS)+/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */+#define DSOCR_ODT_EN(ctrl)         	(ctrl << DSOCR_ODT_EN_OFFS)+#define DSOCR_ODT_SEL_DISABLE	    0	+#define DSOCR_ODT_SEL_75_OHM	    2	+#define DSOCR_ODT_SEL_150_OHM	    1+#define DSOCR_ODT_SEL_50_OHM        3+#define DSOCR_DQ_ODT_SEL_OFFS       10+#define DSOCR_DQ_ODT_SEL_MASK       (0x3 << DSOCR_DQ_ODT_SEL_OFFS)+#define DSOCR_DQ_ODT_SEL(odtSel)    (odtSel << DSOCR_DQ_ODT_SEL_OFFS)+#define DSOCR_ST_ODT_SEL_OFFS       12+#define DSOCR_ST_ODT_SEL_MASK       (0x3 << DSOCR_ST_ODT_SEL_OFFS)+#define DSOCR_ST_ODT_SEL(odtSel)    (odtSel << DSOCR_ST_ODT_SEL_OFFS)+#define DSOCR_ST_ODT_EN             (1 << 14)++/* DDR SDRAM Initialization Control Register (DSICR) */+#define DDR_SDRAM_INIT_CTRL_REG	    (DRAM_BASE + 0x1480)+#define DSICR_INIT_EN		    	(1 << 0)+#define DSICR_T200_SET		    	(1 << 8)++/* sdram extended mode2 register (SEM2R) */+#define SDRAM_EXTENDED_MODE2_REG	(DRAM_BASE + 0x148C)+#define SEM2R_EMRS2_DDR2_OFFS		0+#define SEM2R_EMRS2_DDR2_MASK		(0x7FFF << SEM2R_EMRS2_DDR2_OFFS)++/* sdram extended mode3 register (SEM3R) */+#define SDRAM_EXTENDED_MODE3_REG	(DRAM_BASE + 0x1490)+#define SEM3R_EMRS3_DDR2_OFFS		0+#define SEM3R_EMRS3_DDR2_MASK		(0x7FFF << SEM3R_EMRS3_DDR2_OFFS)++/* sdram error registers */+#define SDRAM_ERROR_CAUSE_REG               	(DRAM_BASE + 0x14d0)+#define SDRAM_ERROR_MASK_REG                	(DRAM_BASE + 0x14d4)+#define SDRAM_ERROR_DATA_LOW_REG            	(DRAM_BASE + 0x1444)+#define SDRAM_ERROR_DATA_HIGH_REG           	(DRAM_BASE + 0x1440)+#define SDRAM_ERROR_ADDR_REG                	(DRAM_BASE + 0x1450)+#define SDRAM_ERROR_ECC_REG                 	(DRAM_BASE + 0x1448)+#define SDRAM_CALC_ECC_REG                  	(DRAM_BASE + 0x144c)+#define SDRAM_ECC_CONTROL_REG               	(DRAM_BASE + 0x1454)+#define SDRAM_SINGLE_BIT_ERR_CNTR_REG 		(DRAM_BASE + 0x1458)+#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG 		(DRAM_BASE + 0x145c)++/* SDRAM Error Cause Register (SECR) */+#define SECR_SINGLE_BIT_ERR			BIT0+#define SECR_DOUBLE_BIT_ERR			BIT1+#define SECR_DATA_PATH_PARITY_ERR	BIT2+/* SDRAM Error Address Register (SEAR) */+#define SEAR_ERR_TYPE_OFFS			0+#define SEAR_ERR_TYPE_MASK      	(1 << SEAR_ERR_TYPE_OFFS)+#define SEAR_ERR_TYPE_SINGLE    	0	+#define SEAR_ERR_TYPE_DOUBLE    	(1 << SEAR_ERR_TYPE_OFFS)+#define SEAR_ERR_CS_OFFS			1+#define SEAR_ERR_CS_MASK			(3 << SEAR_ERR_CS_OFFS)+#define SEAR_ERR_CS(csNum)			(csNum << SEAR_ERR_CS_OFFS)+#define SEAR_ERR_ADDR_OFFS      	3+#define SEAR_ERR_ADDR_MASK      	(0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)++/* SDRAM ECC Control Register (SECR) */+#define SECR_FORCEECC_OFFS          0+#define SECR_FORCEECC_MASK          (0xFF << SECR_FORCEECC_OFFS)+#define SECR_FORCEEN_OFFS           8+#define SECR_FORCEEN_MASK           (1 << SECR_FORCEEN_OFFS)+#define SECR_ECC_CALC_MASK          (0 << SECR_FORCEEN_OFFS)+#define SECR_ECC_USER_MASK          (1 << SECR_FORCEEN_OFFS)+#define SECR_PERRPROP_EN            BIT9+#define SECR_CNTMODE_OFFS           10+#define SECR_CNTMODE_MASK           (1 << SECR_CNTMODE_OFFS)+#define SECR_ALL_IN_CS0             (0 << SECR_CNTMODE_OFFS)+#define SECR_NORMAL_COUNTER         (1 << SECR_CNTMODE_OFFS)+#define SECR_THRECC_OFFS            16+#define SECR_THRECC_MAX             0xFF+#define SECR_THRECC_MASK            (SECR_THRECC_MAX << SECR_THRECC_OFFS)+#define SECR_THRECC(threshold)      (threshold << SECR_THRECC_OFFS)+++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvDramIfRegsh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h	2010-11-09 20:28:10.962495352 +0100@@ -0,0 +1,179 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvDramIfStaticInith+#define __INCmvDramIfStaticInith++#ifdef MV_STATIC_DRAM_ON_BOARD+#define STATIC_DRAM_BANK_1+#undef	STATIC_DRAM_BANK_2             +#undef	STATIC_DRAM_BANK_3                         +#undef 	STATIC_DRAM_BANK_4             +++#ifdef MV_DIMM_TS256MLQ72V5U+#define	STATIC_DRAM_BANK_2             +#define	STATIC_DRAM_BANK_3                         +#undef 	STATIC_DRAM_BANK_4             ++#define STATIC_SDRAM_CONFIG_REG		    0x4724481A  /* offset 0x1400 - DMA reg-0xf1000814 */ +#define STATIC_SDRAM_DUNIT_CTRL_REG         0x37707450  /* offset 0x1404 - DMA reg-0xf100081c */ +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG    0x11A13330  /* offset 0x1408 - DMA reg-0xf1000824 */ +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG   0x00000601  /* offset 0x140c - DMA reg-0xf1000828 */ +#define STATIC_SDRAM_ADDR_CTRL_REG          0x00001CB2  /* offset 0x1410 - DMA reg-0xf1000820 */ +#define STATIC_SDRAM_MODE_REG               0x00000642  /* offset 0x141c - DMA reg-0xf1000818 */ +#define STATIC_SDRAM_ODT_CTRL_LOW	    0x030C030C /*   0x1494  */  +#define STATIC_SDRAM_ODT_CTRL_HI	    0x00000000 /*   0x1498  */  +#define STATIC_SDRAM_DUNIT_ODT_CTRL    	    0x0000740F /*   0x149c  */  +#define STATIC_SDRAM_EXT_MODE          	    0x00000404 /*   0x1420  */  +#define STATIC_SDRAM_DDR2_TIMING_LO         0x00074410 /*   0x1428  */  +#define STATIC_SDRAM_DDR2_TIMING_HI         0x00007441 /*   0x147C  */  ++#define STATIC_SDRAM_RANK0_SIZE_DIMM0       0x3FFF /* size bank0 dimm0   - DMA reg-0xf1000810 */ +#define STATIC_SDRAM_RANK1_SIZE_DIMM0       0x3FFF /* size bank1 dimm0   */ +#define STATIC_SDRAM_RANK0_SIZE_DIMM1       0x3FFF /* size bank0 dimm1   */ +#define STATIC_SDRAM_RANK1_SIZE_DIMM1       0x0	   /* size bank1 dimm1   */ ++#endif /* TS256MLQ72V5U */+++#ifdef MV_MT9VDDT3272AG+/* one DIMM 256M  */+#define STATIC_SDRAM_CONFIG_REG		    0x5820040d  /* offset 0x1400 - DMA reg-0xf1000814 */ +#define STATIC_SDRAM_DUNIT_CTRL_REG         0xC4000540  /* offset 0x1404 - DMA reg-0xf100081c */ +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG    0x01602220  /* offset 0x1408 - DMA reg-0xf1000824 */ +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG   0x0000000b  /* offset 0x140c - DMA reg-0xf1000828 */ +#define STATIC_SDRAM_ADDR_CTRL_REG          0x00000012  /* offset 0x1410 - DMA reg-0xf1000820 */ +#define STATIC_SDRAM_MODE_REG               0x00000062  /* offset 0x141c - DMA reg-0xf1000818 */ +#define STATIC_SDRAM_RANK0_SIZE_DIMM0       0x0fff /* size bank0 dimm0   - DMA reg-0xf1000810 */ +#define STATIC_SDRAM_RANK0_SIZE_DIMM1       0x0    /* size bank0 dimm1   */ ++#endif /* MV_MT9VDDT3272AG */++++#ifdef MV_D27RB12P+/* +Two DIMM 512M + ECC enabled, Registered DIMM  CAS Latency 2.5+*/++#define STATIC_SDRAM_CONFIG_REG		    0x6826081E  /* offset 0x1400 - DMA reg-0xf1000814 */ +#define STATIC_SDRAM_DUNIT_CTRL_REG         0xC5000540  /* offset 0x1404 - DMA reg-0xf100081c */ +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG    0x01501220  /* offset 0x1408 - DMA reg-0xf1000824 */ +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG   0x00000009  /* offset 0x140c - DMA reg-0xf1000828 */ +#define STATIC_SDRAM_ADDR_CTRL_REG          0x00000012  /* offset 0x1410 - DMA reg-0xf1000820 */ +#define STATIC_SDRAM_MODE_REG               0x00000062  /* offset 0x141c - DMA reg-0xf1000818 */ +#define STATIC_SDRAM_RANK0_SIZE_DIMM0       0x0FFF /* size bank0 dimm0   - DMA reg-0xf1000810 */ +#define STATIC_SDRAM_RANK0_SIZE_DIMM1       0x0FFF    /* size bank0 dimm1   */ ++#define STATIC_DRAM_BANK_2             ++#define STATIC_DRAM_BANK_3                         +#define STATIC_DRAM_BANK_4             ++#endif /*  mv_D27RB12P  */++#ifdef RD_MV645XX++#define STATIC_MEM_TYPE				MEM_TYPE_DDR2+#define STATIC_DIMM_INFO_BANK0_SIZE		256+/* DDR2 boards 256 MB*/++#define STATIC_SDRAM_RANK0_SIZE_DIMM0       	0x00000fff /* size bank0 dimm0   - DMA reg-0xf1000810 */ +#define STATIC_SDRAM_CONFIG_REG	     		0x07190618	+#define STATIC_SDRAM_MODE_REG	     		0x00000432	+#define STATIC_SDRAM_DUNIT_CTRL_REG     	0xf4a03440+#define STATIC_SDRAM_ADDR_CTRL_REG	     	0x00000022+#define STATIC_SDRAM_TIMING_CTRL_LOW_REG    	0x11712220+#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG	0x00000504+#define STATIC_SDRAM_ODT_CTRL_LOW	     	0x84210000+#define STATIC_SDRAM_ODT_CTRL_HI	     	0x00000000+#define STATIC_SDRAM_DUNIT_ODT_CTRL    		0x0000780f+#define STATIC_SDRAM_EXT_MODE          		0x00000440+#define STATIC_SDRAM_DDR2_TIMING_LO         	0x00063300+#define STATIC_SDRAM_DDR2_TIMING_HI         	0x00006330+#endif /* RD_MV645XX */++#if MV_DIMM_M3783354CZ3_CE6 ++#define STATIC_SDRAM_RANK0_SIZE_DIMM0		0x00000FFF /* 0x2010 size bank0 dimm0   - DMA reg-0xf1000810 */ +#define STATIC_SDRAM_CONFIG_REG	     		0x07190618 /*   0x1400  */ +#define STATIC_SDRAM_MODE_REG	     		0x00000432 /*   0x141c  */  +#define STATIC_SDRAM_DUNIT_CTRL_REG     	0xf4a03440 /*   0x1404  */  +#define STATIC_SDRAM_ADDR_CTRL_REG	     	0x00000022 /*   0x1410  */  +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG	0x11712220 /*   0x1408  */  +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG	0x00000504 /*   0x140c  */  +#define STATIC_SDRAM_ODT_CTRL_LOW	     	0x84210000 /*   0x1494  */  +#define STATIC_SDRAM_ODT_CTRL_HI	     	0x00000000 /*   0x1498  */  +#define STATIC_SDRAM_DUNIT_ODT_CTRL    		0x0000780f /*   0x149c  */  +#define STATIC_SDRAM_EXT_MODE          		0x00000440 /*   0x1420  */  +#define STATIC_SDRAM_DDR2_TIMING_LO		0x00063300 /*   0x1428  */  +#define STATIC_SDRAM_DDR2_TIMING_HI		0x00006330 /*   0x147C  */  ++#endif /* MV_DIMM_M3783354CZ3_CE6 */++#endif /* MV_STATIC_DRAM_ON_BOARD */+#endif /* __INCmvDramIfStaticInith */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c	2010-11-09 20:28:11.002495540 +0100@@ -0,0 +1,1474 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "ddr2/spd/mvSpd.h"+#include "boardEnv/mvBoardEnvLib.h"++/* #define MV_DEBUG */+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo, +                                            MV_DRAM_BANK_INFO *pBankInfo);+static MV_U32  cas2ps(MV_U8 spd_byte);+/*******************************************************************************+* mvDramBankGet - Get the DRAM bank paramters.+*+* DESCRIPTION:+*       This function retrieves DRAM bank parameters as described in +*       DRAM_BANK_INFO struct to the controller DRAM unit. In case the board +*       has its DRAM on DIMMs it will use its EEPROM to extract SPD data+*       from it. Otherwise, if the DRAM is soldered on board, the function +*       should insert its bank information into MV_DRAM_BANK_INFO struct.+*+* INPUT:+*       bankNum  - Board DRAM bank number.+*+* OUTPUT:+*       pBankInfo  - DRAM bank information struct.+*+* RETURN:+*       MV_FAIL - Bank parameters could not be read.+*+*******************************************************************************/+MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)+{+    MV_DIMM_INFO dimmInfo;++    DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum)); +    /* zero pBankInfo structure */++    if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))+    {+        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n")); +        return MV_BAD_PARAM;+    }+    memset(pBankInfo, 0, sizeof(*pBankInfo));++	if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))+	{+		DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));+		return MV_FAIL;+	}+	if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))+	{+		DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));+		return MV_FAIL;+	}+	/* convert Dimm info to Bank info */+    cpyDimm2BankInfo(&dimmInfo, pBankInfo);+    return MV_OK;+}++/*******************************************************************************+* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.+*+* DESCRIPTION:+*       Convert a Dimm info struct into a bank info struct.+*+* INPUT:+*       pDimmInfo - DIMM information structure.+*+* OUTPUT:+*       pBankInfo  - DRAM bank information struct.+*+* RETURN:+*       None.+*+*******************************************************************************/+static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo, +                                                MV_DRAM_BANK_INFO *pBankInfo)+{+    pBankInfo->memoryType = pDimmInfo->memoryType;        ++    /* DIMM dimensions */+    pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;+    pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;+    pBankInfo->dataWidth = pDimmInfo->dataWidth;+    pBankInfo->errorCheckType = pDimmInfo->errorCheckType;             +    pBankInfo->sdramWidth = pDimmInfo->sdramWidth;+    pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;   +    pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;+    pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;+    pBankInfo->refreshInterval = pDimmInfo->refreshInterval;+ +    /* DIMM timing parameters */+    pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;+    pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps = +                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;+    pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps = +                                    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;++    pBankInfo->minRowPrechargeTime     = pDimmInfo->minRowPrechargeTime;     +    pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;+    pBankInfo->minRasToCasDelay        = pDimmInfo->minRasToCasDelay;       +    pBankInfo->minRasPulseWidth        = pDimmInfo->minRasPulseWidth;       +    pBankInfo->minWriteRecoveryTime    = pDimmInfo->minWriteRecoveryTime;+    pBankInfo->minWriteToReadCmdDelay  = pDimmInfo->minWriteToReadCmdDelay;+    pBankInfo->minReadToPrechCmdDelay  = pDimmInfo->minReadToPrechCmdDelay;+    pBankInfo->minRefreshToActiveCmd   = pDimmInfo->minRefreshToActiveCmd;+               +    /* Parameters calculated from the extracted DIMM information */+    pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;+    pBankInfo->deviceDensity = pDimmInfo->deviceDensity;              +    pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /+                                 pDimmInfo->numOfModuleBanks;+ +    /* DIMM attributes (MV_TRUE for yes) */++    if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||+        (pDimmInfo->memoryType == MEM_TYPE_DDR1)   )+    {   +        if (pDimmInfo->dimmAttributes & BIT1)+            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;+        else+            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;+    }+    else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */+    {+        if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))+            pBankInfo->registeredAddrAndControlInputs = MV_TRUE;+        else+            pBankInfo->registeredAddrAndControlInputs = MV_FALSE;+    }++    return;+}+/*******************************************************************************+* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.+*+* DESCRIPTION:+*       Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.+*+*******************************************************************************/+MV_STATUS dimmSpdCpy(MV_VOID)+{+    MV_U32 i;+    MV_U32 spdChecksum;+     +    MV_TWSI_SLAVE twsiSlave;+    MV_U8 data[SPD_SIZE];++    /* zero dimmInfo structure */+    memset(data, 0, SPD_SIZE);++    /* read the dimm eeprom */+    DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));+    twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;+    twsiSlave.slaveAddr.type = ADDR7_BIT;+    twsiSlave.validOffset = MV_TRUE;+    twsiSlave.offset = 0;+    twsiSlave.moreThen256 = MV_FALSE;++    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )+    {+        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));+        return MV_FAIL;+    }+    DB(puts("DRAM: Reading dimm info succeded.\n"));+    +    /* calculate SPD checksum */+    spdChecksum = 0;+    +    for(i = 0 ; i <= 62 ; i++)+    {+        spdChecksum += data[i];+    }+    +    if ((spdChecksum & 0xff) != data[63])+    {+        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",+                            (MV_U32)(spdChecksum & 0xff), data[63]));+    }+    else+    {+        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));+    }++    /* copy the SPD content 1:1 into the DIMM 1 SPD */+    twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;+    twsiSlave.slaveAddr.type = ADDR7_BIT;+    twsiSlave.validOffset = MV_TRUE;+    twsiSlave.offset = 0;+    twsiSlave.moreThen256 = MV_FALSE;++    for(i = 0 ; i < SPD_SIZE ; i++)+    {+	twsiSlave.offset = i;+	if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )+	{+	    mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);+	    return MV_FAIL;+	}+	mvOsDelay(5);+    }+    +    DB(puts("DRAM: Reading dimm info succeded.\n"));+    return MV_OK;+}++/*******************************************************************************+* dimmSpdGet - Get the SPD parameters.+*+* DESCRIPTION:+*       Read the DIMM SPD parameters into given struct parameter.+*+* INPUT:+*       dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.+*+* OUTPUT:+*       pDimmInfo - DIMM information structure.+*+* RETURN:+*       MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.+*+*******************************************************************************/+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)+{+    MV_U32 i;+    MV_U32 density = 1;+    MV_U32 spdChecksum;+     +    MV_TWSI_SLAVE twsiSlave;+    MV_U8 data[SPD_SIZE];++    if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))+    {+        DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n")); +        return MV_BAD_PARAM;+    }++    /* zero dimmInfo structure */+    memset(data, 0, SPD_SIZE);++    /* read the dimm eeprom */+    DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));+    twsiSlave.slaveAddr.address = (dimmNum == 0) ?+                            MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;+    twsiSlave.slaveAddr.type = ADDR7_BIT;+    twsiSlave.validOffset = MV_TRUE;+    twsiSlave.offset = 0;+    twsiSlave.moreThen256 = MV_FALSE;++    if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )+    {+        DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));+        return MV_FAIL;+    }+    DB(puts("DRAM: Reading dimm info succeded.\n"));+    +    /* calculate SPD checksum */+    spdChecksum = 0;+    +        for(i = 0 ; i <= 62 ; i++)+        {+        spdChecksum += data[i];+    }+    +    if ((spdChecksum & 0xff) != data[63])+    {+        DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",+                            (MV_U32)(spdChecksum & 0xff), data[63]));+    }+    else+    {+        DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));+    }++    /* copy the SPD content 1:1 into the dimmInfo structure*/+    for(i = 0 ; i < SPD_SIZE ; i++)+    {+        pDimmInfo->spdRawData[i] = data[i];+        DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));+    }++    DB(mvOsPrintf("DRAM SPD Information:\n"));++    /* Memory type (DDR / SDRAM) */+    switch (data[DIMM_MEM_TYPE])+    {+        case (DIMM_MEM_TYPE_SDRAM):+            pDimmInfo->memoryType = MEM_TYPE_SDRAM;+            DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));+            break;+        case (DIMM_MEM_TYPE_DDR1):+            pDimmInfo->memoryType = MEM_TYPE_DDR1;+            DB(mvOsPrintf("DRAM Memeory type DDR1\n"));+            break;+        case (DIMM_MEM_TYPE_DDR2):+            pDimmInfo->memoryType = MEM_TYPE_DDR2;+            DB(mvOsPrintf("DRAM Memeory type DDR2\n"));+            break;+        default:+            mvOsPrintf("ERROR: Undefined memory type!\n");+            return MV_ERROR;+    }++    +    /* Number Of Row Addresses */+    pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];+    DB(mvOsPrintf("DRAM numOfRowAddr[3]         %d\n",pDimmInfo->numOfRowAddr));+        +    /* Number Of Column Addresses */+    pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];+    DB(mvOsPrintf("DRAM numOfColAddr[4]         %d\n",pDimmInfo->numOfColAddr));+        +    /* Number Of Module Banks */+    pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];+    DB(mvOsPrintf("DRAM numOfModuleBanks[5]     0x%x\n", +                                                  pDimmInfo->numOfModuleBanks));+        +    /* Number of module banks encoded differently for DDR2 */+    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)+        pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;++    /* Data Width */+    pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];+    DB(mvOsPrintf("DRAM dataWidth[6]            0x%x\n", pDimmInfo->dataWidth));+        +    /* Minimum Cycle Time At Max CasLatancy */+    pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);++    /* Error Check Type */+    pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];+    DB(mvOsPrintf("DRAM errorCheckType[11]      0x%x\n", +                                                    pDimmInfo->errorCheckType));++    /* Refresh Interval */+    pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];+    DB(mvOsPrintf("DRAM refreshInterval[12]     0x%x\n", +                                                   pDimmInfo->refreshInterval));+    +    /* Sdram Width */+    pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];+    DB(mvOsPrintf("DRAM sdramWidth[13]          0x%x\n",pDimmInfo->sdramWidth));+        +    /* Error Check Data Width */+    pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];+    DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n", +                                               pDimmInfo->errorCheckDataWidth));+    +    /* Burst Length Supported */+    /*     SDRAM/DDR1:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   |  2   |   1  * +                    *********************************************************/ +    /*     DDR2:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   | TBD  | TBD  * +                    *********************************************************/ ++    pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];+    DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n", +                                              pDimmInfo->burstLengthSupported));+    +    /* Number Of Banks On Each Device */+    pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];+    DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n", +                                            pDimmInfo->numOfBanksOnEachDevice));+    +    /* Suported Cas Latencies */+                   +    /*      SDRAM:+            *******-******-******-******-******-******-******-******* +            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +            *******-******-******-******-******-******-******-******* +    CAS =   * TBD  |  7   |  6   |  5   |  4   |  3   |   2  |   1  * +            ********************************************************/ ++    /*     DDR 1:+            *******-******-******-******-******-******-******-******* +            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +            *******-******-******-******-******-******-******-******* +    CAS =   * TBD  |  4   | 3.5  |   3  | 2.5  |  2   | 1.5  |   1  * +            *********************************************************/++    /*     DDR 2:+            *******-******-******-******-******-******-******-******* +            * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +            *******-******-******-******-******-******-******-******* +    CAS =   * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * +            *********************************************************/+    +    pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];+    DB(mvOsPrintf("DRAM suportedCasLatencies[18]    0x%x\n", +                                              pDimmInfo->suportedCasLatencies));++    /* For DDR2 only, get the DIMM type information */+    if (pDimmInfo->memoryType == MEM_TYPE_DDR2)+    {   +        pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];+        DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n", +                                                      pDimmInfo->dimmTypeInfo));+    }++    /* SDRAM Modules Attributes */+    pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];+    DB(mvOsPrintf("DRAM dimmAttributes[21]          0x%x\n",    +                                                    pDimmInfo->dimmAttributes));+    +    /* Minimum Cycle Time At Max CasLatancy Minus 1*/+    pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps = +                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);++    /* Minimum Cycle Time At Max CasLatancy Minus 2*/+    pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps = +                                    cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);++    pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];+    DB(mvOsPrintf("DRAM minRowPrechargeTime[27]     0x%x\n", +                                               pDimmInfo->minRowPrechargeTime));+    pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];+    DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n", +                                           pDimmInfo->minRowActiveToRowActive));+    pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];+    DB(mvOsPrintf("DRAM minRasToCasDelay[29]        0x%x\n", +                                                  pDimmInfo->minRasToCasDelay));+    pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];+    DB(mvOsPrintf("DRAM minRasPulseWidth[30]        0x%x\n", +                                                  pDimmInfo->minRasPulseWidth));+        +    /* DIMM Bank Density */+    pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];+    DB(mvOsPrintf("DRAM dimmBankDensity[31]         0x%x\n", +                                                   pDimmInfo->dimmBankDensity));++    /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore     */+    pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];+    DB(mvOsPrintf("DRAM minWriteRecoveryTime[36]    0x%x\n", +                                              pDimmInfo->minWriteRecoveryTime));+    +    /* Only DDR2 includes Internal Write To Read Command Delay field.       */+    pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];+    DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37]  0x%x\n", +                                            pDimmInfo->minWriteToReadCmdDelay));+    +    /* Only DDR2 includes Internal Read To Precharge Command Delay field.   */+    pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];+    DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38]  0x%x\n",    +                                            pDimmInfo->minReadToPrechCmdDelay));+    +    /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */+    pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];+    DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42]   0x%x\n", +                                             pDimmInfo->minRefreshToActiveCmd));+                 +    /* calculating the sdram density. Representing device density from      */+    /* bit 20 to allow representation of 4GB and above.                     */+    /* For example, if density is 512Mbit 0x20000000, will be represent in  */+    /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example    */+    /* is density 8GB 0x200000000 >> 16 --> 0x00002000.                     */+    density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));+    pDimmInfo->deviceDensity = density * +                                pDimmInfo->numOfBanksOnEachDevice * +                                pDimmInfo->sdramWidth;+    DB(mvOsPrintf("DRAM deviceDensity           %d\n",pDimmInfo->deviceDensity));+    +    /* Number of devices includeing Error correction */+    pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) * +                                  pDimmInfo->numOfModuleBanks;+    DB(mvOsPrintf("DRAM numberOfDevices         %d\n",  +                                                   pDimmInfo->numberOfDevices));++    pDimmInfo->size = 0; ++    /* Note that pDimmInfo->size is in MB units */+    if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)+    {+        if (pDimmInfo->dimmBankDensity & BIT0)+            pDimmInfo->size += 1024;                /* Equal to 1GB     */+        else if (pDimmInfo->dimmBankDensity & BIT1)+            pDimmInfo->size += 8;                   /* Equal to 8MB     */+        else if (pDimmInfo->dimmBankDensity & BIT2)+            pDimmInfo->size += 16;                  /* Equal to 16MB    */+        else if (pDimmInfo->dimmBankDensity & BIT3)+            pDimmInfo->size += 32;                  /* Equal to 32MB    */+        else if (pDimmInfo->dimmBankDensity & BIT4)+            pDimmInfo->size += 64;                  /* Equal to 64MB    */+        else if (pDimmInfo->dimmBankDensity & BIT5)+            pDimmInfo->size += 128;                 /* Equal to 128MB   */+        else if (pDimmInfo->dimmBankDensity & BIT6) +            pDimmInfo->size += 256;                 /* Equal to 256MB   */+        else if (pDimmInfo->dimmBankDensity & BIT7) +            pDimmInfo->size += 512;                 /* Equal to 512MB   */+    }+    else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)+    {+        if (pDimmInfo->dimmBankDensity & BIT0)+            pDimmInfo->size += 1024;                /* Equal to 1GB     */+        else if (pDimmInfo->dimmBankDensity & BIT1)+            pDimmInfo->size += 2048;                /* Equal to 2GB     */+        else if (pDimmInfo->dimmBankDensity & BIT2)+            pDimmInfo->size += 16;                  /* Equal to 16MB    */+        else if (pDimmInfo->dimmBankDensity & BIT3)+            pDimmInfo->size += 32;                  /* Equal to 32MB    */+        else if (pDimmInfo->dimmBankDensity & BIT4)+            pDimmInfo->size += 64;                  /* Equal to 64MB    */+        else if (pDimmInfo->dimmBankDensity & BIT5)+            pDimmInfo->size += 128;                 /* Equal to 128MB   */+        else if (pDimmInfo->dimmBankDensity & BIT6) +            pDimmInfo->size += 256;                 /* Equal to 256MB   */+        else if (pDimmInfo->dimmBankDensity & BIT7) +            pDimmInfo->size += 512;                 /* Equal to 512MB   */+    }+    else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */+    {+        if (pDimmInfo->dimmBankDensity & BIT0)+            pDimmInfo->size += 1024;                /* Equal to 1GB     */+        else if (pDimmInfo->dimmBankDensity & BIT1)+            pDimmInfo->size += 2048;                /* Equal to 2GB     */+        else if (pDimmInfo->dimmBankDensity & BIT2)+            pDimmInfo->size += 4096;                /* Equal to 4GB     */+        else if (pDimmInfo->dimmBankDensity & BIT3)+            pDimmInfo->size += 8192;                /* Equal to 8GB     */+        else if (pDimmInfo->dimmBankDensity & BIT4)+            pDimmInfo->size += 16384;               /* Equal to 16GB    */+        else if (pDimmInfo->dimmBankDensity & BIT5)+            pDimmInfo->size += 128;                 /* Equal to 128MB   */+        else if (pDimmInfo->dimmBankDensity & BIT6) +            pDimmInfo->size += 256;                 /* Equal to 256MB   */+        else if (pDimmInfo->dimmBankDensity & BIT7) +            pDimmInfo->size += 512;                 /* Equal to 512MB   */+    }+    +    pDimmInfo->size *= pDimmInfo->numOfModuleBanks;++    DB(mvOsPrintf("Dram: dimm size    %dMB \n",pDimmInfo->size));++    return MV_OK;+}++/*******************************************************************************+* dimmSpdPrint - Print the SPD parameters.+*+* DESCRIPTION:+*       Print the Dimm SPD parameters.+*+* INPUT:+*       pDimmInfo - DIMM information structure.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_VOID dimmSpdPrint(MV_U32 dimmNum)+{+    MV_DIMM_INFO dimmInfo;+    MV_U32  i, temp = 0;+    MV_U32  k, maskLeftOfPoint = 0, maskRightOfPoint = 0;+    MV_U32  rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;+    MV_U32  busClkPs;+    MV_U8   trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,+            temp_buf[40], *spdRawData;++    busClkPs = 1000000000 / (mvBoardSysClkGet() / 100);  /* in 10 ps units */++    spdRawData = dimmInfo.spdRawData;+    +    if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))+    {+        mvOsOutput("ERROR: Could not read SPD information!\n");+        return;+    }++    /* find Manufactura of Dimm Module */+    mvOsOutput("\nManufacturer's JEDEC ID Code:   ");+    for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)+    {+        mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);+    }+    mvOsOutput("\n");++    /* Manufacturer's Specific Data */+    for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)+    {+        temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];+    }+    mvOsOutput("Manufacturer's Specific Data:   %s\n", temp_buf);++    /* Module Part Number */+    for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)+    {+        temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];+    }+    mvOsOutput("Module Part Number:             %s\n", temp_buf);++    /* Module Serial Number */+    for(i = 0; i < sizeof(MV_U32); i++)+    {+    	temp |= spdRawData[95+i] << 8*i;+    }+    mvOsOutput("DIMM Serial No.                 %ld (%lx)\n", (long)temp, +                                    (long)temp);++    /* find Manufac-Data of Dimm Module */+    mvOsOutput("Manufactoring Date:             Year 20%d%d/ ww %d%d\n", +                        ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf), +                        ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf)); +    /* find modul_revision of Dimm Module */+    mvOsOutput("Module Revision:                %d.%d\n", +               spdRawData[62]/10, spdRawData[62]%10); ++    /* find manufac_place of Dimm Module */+    mvOsOutput("manufac_place:                  %d\n", spdRawData[72]);+    +    /* go over the first 35 I2C data bytes */+    for(i = 2 ; i <= 35 ; i++)+       switch(i)+        {+            case 2:  /* Memory type (DDR1/2 / SDRAM) */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                    mvOsOutput("Dram Type is:                   SDRAM\n");+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                    mvOsOutput("Dram Type is:                   SDRAM DDR1\n");+                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                    mvOsOutput("Dram Type is:                   SDRAM DDR2\n");+                else+                    mvOsOutput("Dram Type unknown\n");+                break;+/*----------------------------------------------------------------------------*/++            case 3:  /* Number Of Row Addresses */+                mvOsOutput("Module Number of row addresses: %d\n", +                                                        dimmInfo.numOfRowAddr);+                break;+/*----------------------------------------------------------------------------*/+    +            case 4:  /* Number Of Column Addresses */+                mvOsOutput("Module Number of col addresses: %d\n", +                                                        dimmInfo.numOfColAddr);+                break;+/*----------------------------------------------------------------------------*/+    +            case 5:  /* Number Of Module Banks */+                mvOsOutput("Number of Banks on Mod.:        %d\n",  +                                                    dimmInfo.numOfModuleBanks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 6:  /* Data Width */+                mvOsOutput("Module Data Width:              %d bit\n",  +                                                           dimmInfo.dataWidth);+                break;+/*----------------------------------------------------------------------------*/+    +            case 8:  /* Voltage Interface */+                switch(spdRawData[i])+                {+                    case 0x0:+                        mvOsOutput("Module is               TTL_5V_TOLERANT\n");+                        break;+                    case 0x1:+                        mvOsOutput("Module is               LVTTL\n");+                        break;+                    case 0x2:+                        mvOsOutput("Module is               HSTL_1_5V\n");+                        break;+                    case 0x3:+                        mvOsOutput("Module is               SSTL_3_3V\n");+                        break;+                    case 0x4:+                        mvOsOutput("Module is               SSTL_2_5V\n");+                        break;+                    case 0x5:+                        if (dimmInfo.memoryType != MEM_TYPE_SDRAM)+                        {+                            mvOsOutput("Module is                 SSTL_1_8V\n");+                            break;+                        }+                    default:+                        mvOsOutput("Module is               VOLTAGE_UNKNOWN\n");+                        break;+                }+                break;+/*----------------------------------------------------------------------------*/+    +            case 9:  /* Minimum Cycle Time At Max CasLatancy */+                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;+                rightOfPoint = (spdRawData[i] & 0x0f) * 10;+                +                /* DDR2 addition of right of point */+                if ((spdRawData[i] & 0x0f) == 0xA)+                {+                    rightOfPoint = 25;+                }+                if ((spdRawData[i] & 0x0f) == 0xB)+                {+                    rightOfPoint = 33;+                }+                if ((spdRawData[i] & 0x0f) == 0xC)+                {+                    rightOfPoint = 66;+                }+                if ((spdRawData[i] & 0x0f) == 0xD)+                {+                    rightOfPoint = 75;+                }+                mvOsOutput("Minimum Cycle Time At Max CL:   %d.%d [ns]\n",+                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 10: /* Clock To Data Out */+                div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;+                time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                leftOfPoint     = time_tmp / div;+                rightOfPoint    = time_tmp % div;+                mvOsOutput("Clock To Data Out:              %d.%d [ns]\n",+                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 11: /* Error Check Type */+                mvOsOutput("Error Check Type (0=NONE):      %d\n", +                                                      dimmInfo.errorCheckType);+                break;+/*----------------------------------------------------------------------------*/++            case 12: /* Refresh Interval */+                mvOsOutput("Refresh Rate:                   %x\n", +                                                     dimmInfo.refreshInterval);+                break;+/*----------------------------------------------------------------------------*/+    +            case 13: /* Sdram Width */+                mvOsOutput("Sdram Width:                    %d bits\n",     +                                                          dimmInfo.sdramWidth);+                break;+/*----------------------------------------------------------------------------*/+    +            case 14: /* Error Check Data Width */+                mvOsOutput("Error Check Data Width:         %d bits\n", +                                                 dimmInfo.errorCheckDataWidth);+                break;+/*----------------------------------------------------------------------------*/++           case 15: /* Minimum Clock Delay is unsupported */+                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||+                    (dimmInfo.memoryType == MEM_TYPE_DDR1))+                {+                    mvOsOutput("Minimum Clk Delay back to back: %d\n", +                                                                spdRawData[i]);+                }+                break;+/*----------------------------------------------------------------------------*/+    +            case 16: /* Burst Length Supported */+    /*     SDRAM/DDR1:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   |  2   |   1  * +                    *********************************************************/ +    /*     DDR2:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +    burst length =  * Page | TBD  | TBD  | TBD  |  8   |  4   | TBD  | TBD  * +                    *********************************************************/ +                mvOsOutput("Burst Length Supported: ");+                if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||+                    (dimmInfo.memoryType == MEM_TYPE_DDR1))+                {+                    if (dimmInfo.burstLengthSupported & BIT0)+                        mvOsOutput("1, ");+                    if (dimmInfo.burstLengthSupported & BIT1)+                        mvOsOutput("2, ");+                }+                if (dimmInfo.burstLengthSupported & BIT2)+                    mvOsOutput("4, ");+                if (dimmInfo.burstLengthSupported & BIT3) +                    mvOsOutput("8, ");+                +                mvOsOutput(" Bit \n");+                break;+/*----------------------------------------------------------------------------*/+    +            case 17: /* Number Of Banks On Each Device */+                mvOsOutput("Number Of Banks On Each Chip:   %d\n",  +                                              dimmInfo.numOfBanksOnEachDevice);+                break;+/*----------------------------------------------------------------------------*/+    +            case 18: /* Suported Cas Latencies */+                   +            /*      SDRAM:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +            CAS =   * TBD  |  7   |  6   |  5   |  4   |  3   |   2  |   1  * +                    ********************************************************/ ++            /*     DDR 1:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +            CAS =   * TBD  |  4   | 3.5  |   3  | 2.5  |  2   | 1.5  |   1  * +                    *********************************************************/++            /*     DDR 2:+                    *******-******-******-******-******-******-******-******* +                    * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 * +                    *******-******-******-******-******-******-******-******* +            CAS =   * TBD  | TBD  |  5   |  4   |  3   |  2   | TBD  | TBD  * +                    *********************************************************/++                mvOsOutput("Suported Cas Latencies: (CL) 			");+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    for (k = 0; k <=7; k++)+                    {+                        if (dimmInfo.suportedCasLatencies & (1 << k))+                            mvOsOutput("%d,             ", k+1);+                    }+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if (dimmInfo.suportedCasLatencies & BIT0)+                        mvOsOutput("1, ");+                    if (dimmInfo.suportedCasLatencies & BIT1)+                        mvOsOutput("1.5, ");+                    if (dimmInfo.suportedCasLatencies & BIT2)+                        mvOsOutput("2, ");+                    if (dimmInfo.suportedCasLatencies & BIT3)+                        mvOsOutput("2.5, ");+                    if (dimmInfo.suportedCasLatencies & BIT4)+                        mvOsOutput("3, ");+                    if (dimmInfo.suportedCasLatencies & BIT5)+                        mvOsOutput("3.5, ");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                {+                    if (dimmInfo.suportedCasLatencies & BIT2)+                        mvOsOutput("2, ");+                    if (dimmInfo.suportedCasLatencies & BIT3)+                        mvOsOutput("3, ");+                    if (dimmInfo.suportedCasLatencies & BIT4)+                        mvOsOutput("4, ");+                    if (dimmInfo.suportedCasLatencies & BIT5)+                        mvOsOutput("5, ");		+                }+                else+                    mvOsOutput("?.?, ");		+                mvOsOutput("\n");+                break;+/*----------------------------------------------------------------------------*/+    +            case 20:   /* DDR2 DIMM type info */+                if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                {+                    if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))+                        mvOsOutput("Registered DIMM (RDIMM)\n");+                    else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))+                        mvOsOutput("Unbuffered DIMM (UDIMM)\n");+                    else +                        mvOsOutput("Unknown DIMM type.\n");+                }++                break;+/*----------------------------------------------------------------------------*/+   +            case 21: /* SDRAM Modules Attributes */+                mvOsOutput("\nModule Attributes (SPD Byte 21): \n");+                +                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    if (dimmInfo.dimmAttributes & BIT0)+                        mvOsOutput(" Buffered Addr/Control Input:   Yes\n");+                    else+                        mvOsOutput(" Buffered Addr/Control Input:   No\n");++                    if (dimmInfo.dimmAttributes & BIT1)+                        mvOsOutput(" Registered Addr/Control Input: Yes\n");+                    else+                        mvOsOutput(" Registered Addr/Control Input: No\n");+   +                    if (dimmInfo.dimmAttributes & BIT2)+                        mvOsOutput(" On-Card PLL (clock):           Yes \n");+                    else+                        mvOsOutput(" On-Card PLL (clock):           No \n");++                    if (dimmInfo.dimmAttributes & BIT3)+                        mvOsOutput(" Bufferd DQMB Input:            Yes \n");+                    else+                        mvOsOutput(" Bufferd DQMB Inputs:           No \n");+   +                    if (dimmInfo.dimmAttributes & BIT4)+                        mvOsOutput(" Registered DQMB Inputs:        Yes \n");+                    else+                        mvOsOutput(" Registered DQMB Inputs:        No \n");+ +                    if (dimmInfo.dimmAttributes & BIT5)+                        mvOsOutput(" Differential Clock Input:      Yes \n");+                    else+                        mvOsOutput(" Differential Clock Input:      No \n");+   +                    if (dimmInfo.dimmAttributes & BIT6)+                        mvOsOutput(" redundant Row Addressing:      Yes \n");+                    else+                        mvOsOutput(" redundant Row Addressing:      No \n");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if (dimmInfo.dimmAttributes & BIT0)+                        mvOsOutput(" Buffered Addr/Control Input:   Yes\n");+                    else +                        mvOsOutput(" Buffered Addr/Control Input:   No\n");+   +                    if (dimmInfo.dimmAttributes & BIT1)+                        mvOsOutput(" Registered Addr/Control Input: Yes\n");+                    else+                        mvOsOutput(" Registered Addr/Control Input: No\n");+   +                    if (dimmInfo.dimmAttributes & BIT2)+                        mvOsOutput(" On-Card PLL (clock):           Yes \n");+                    else+                        mvOsOutput(" On-Card PLL (clock):           No \n");+            +                    if (dimmInfo.dimmAttributes & BIT3)+                        mvOsOutput(" FET Switch On-Card Enabled:    Yes \n");+                    else+                        mvOsOutput(" FET Switch On-Card Enabled:    No \n");+                    +                    if (dimmInfo.dimmAttributes & BIT4)+                        mvOsOutput(" FET Switch External Enabled:   Yes \n");+                    else+                        mvOsOutput(" FET Switch External Enabled:   No \n");++                    if (dimmInfo.dimmAttributes & BIT5)+                        mvOsOutput(" Differential Clock Input:      Yes \n");+                    else+                        mvOsOutput(" Differential Clock Input:      No \n");+                }+                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */+                {+                    mvOsOutput(" Number of Active Registers on the DIMM: %d\n", +                                        (dimmInfo.dimmAttributes & 0x3) + 1);+            +                    mvOsOutput(" Number of PLLs on the DIMM: %d\n", +                                      ((dimmInfo.dimmAttributes) >> 2) & 0x3);+               +                    if (dimmInfo.dimmAttributes & BIT4)+                        mvOsOutput(" FET Switch External Enabled:   Yes \n");+                    else+                        mvOsOutput(" FET Switch External Enabled:   No \n");++                    if (dimmInfo.dimmAttributes & BIT6)+                        mvOsOutput(" Analysis probe installed:      Yes \n");+                    else+                        mvOsOutput(" Analysis probe installed:      No \n");+                }+                +                break;+/*----------------------------------------------------------------------------*/++            case 22: /* Suported AutoPreCharge */+                mvOsOutput("\nModul Attributes (SPD Byte 22): \n");+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    if ( spdRawData[i] & BIT0 )+                        mvOsOutput(" Early Ras Precharge:           Yes \n");+                    else+                        mvOsOutput(" Early Ras Precharge:           No \n");+                                                        +                    if ( spdRawData[i] & BIT1 )                 +                        mvOsOutput(" AutoPreCharge:                 Yes \n");+                    else+                        mvOsOutput(" AutoPreCharge:                 No \n");+                                                            +                    if ( spdRawData[i] & BIT2 )                 +                        mvOsOutput(" Precharge All:                 Yes \n");+                    else+                        mvOsOutput(" Precharge All:                 No \n");+                                                        +                    if ( spdRawData[i] & BIT3 )                 +                        mvOsOutput(" Write 1/ReadBurst:             Yes \n");+                    else+                        mvOsOutput(" Write 1/ReadBurst:             No \n");+                                                        +                    if ( spdRawData[i] & BIT4 )                 +                        mvOsOutput(" lower VCC tolerance:           5%%\n");+                    else+                        mvOsOutput(" lower VCC tolerance:           10%%\n");+                                                        +                    if ( spdRawData[i] & BIT5 )                 +                        mvOsOutput(" upper VCC tolerance:           5%%\n");+                    else+                        mvOsOutput(" upper VCC tolerance:           10%%\n");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if ( spdRawData[i] & BIT0 )+                        mvOsOutput(" Supports Weak Driver:          Yes \n");+                    else+                        mvOsOutput(" Supports Weak Driver:          No \n");++                    if ( !(spdRawData[i] & BIT4) )+                        mvOsOutput(" lower VCC tolerance:           0.2V\n");+   +                    if ( !(spdRawData[i] & BIT5) )+                        mvOsOutput(" upper VCC tolerance:           0.2V\n");++                    if ( spdRawData[i] & BIT6 )+                        mvOsOutput(" Concurrent Auto Preharge:      Yes \n");+                    else+                        mvOsOutput(" Concurrent Auto Preharge:      No \n");++                    if ( spdRawData[i] & BIT7 )+                        mvOsOutput(" Supports Fast AP:              Yes \n");+                    else+                        mvOsOutput(" Supports Fast AP:              No \n");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR2)+                {+                    if ( spdRawData[i] & BIT0 )+                        mvOsOutput(" Supports Weak Driver:          Yes \n");+                    else+                        mvOsOutput(" Supports Weak Driver:          No \n");+                }+                break;+/*----------------------------------------------------------------------------*/+    +            case 23:+            /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */+                leftOfPoint = (spdRawData[i] & 0xf0) >> 4;+                rightOfPoint = (spdRawData[i] & 0x0f) * 10;+                +                /* DDR2 addition of right of point */+                if ((spdRawData[i] & 0x0f) == 0xA)+                {+                    rightOfPoint = 25;+                }+                if ((spdRawData[i] & 0x0f) == 0xB)+                {+                    rightOfPoint = 33;+                }+                if ((spdRawData[i] & 0x0f) == 0xC)+                {+                    rightOfPoint = 66;+                }+                if ((spdRawData[i] & 0x0f) == 0xD)+                {+                    rightOfPoint = 75;+                }++                mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"+                           "(0 = Not supported): %d.%d [ns]\n",+                           leftOfPoint, rightOfPoint );+                break;+/*----------------------------------------------------------------------------*/+    +            case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/+                div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;+                time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                    ((spdRawData[i] & 0x0f));+                leftOfPoint     = time_tmp / div;+                rightOfPoint    = time_tmp % div;+                mvOsOutput("Clock To Data Out (2nd CL value): 		%d.%d [ns]\n",+                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 25: +            /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;+                    rightOfPoint = (spdRawData[i] & 0x3) * 25;+                }+                else    /* DDR1 or DDR2 */ +                {+                    leftOfPoint = (spdRawData[i] & 0xf0) >> 4;+                    rightOfPoint = (spdRawData[i] & 0x0f) * 10;+                    +                    /* DDR2 addition of right of point */+                    if ((spdRawData[i] & 0x0f) == 0xA)+                    {+                        rightOfPoint = 25;+                    }+                    if ((spdRawData[i] & 0x0f) == 0xB)+                    {+                        rightOfPoint = 33;+                    }+                    if ((spdRawData[i] & 0x0f) == 0xC)+                    {+                        rightOfPoint = 66;+                    }+                    if ((spdRawData[i] & 0x0f) == 0xD)+                    {+                        rightOfPoint = 75;+                    }+                }+                mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy" +                           "(0 = Not supported): %d.%d [ns]\n",+                           leftOfPoint, rightOfPoint );+                break;+/*----------------------------------------------------------------------------*/+    +            case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    leftOfPoint = (spdRawData[i] & 0xfc) >> 2;+                    rightOfPoint = (spdRawData[i] & 0x3) * 25;+                }+                else    /* DDR1 or DDR2 */ +                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint     = 0;+                    rightOfPoint    = time_tmp;+                }+                mvOsOutput("Clock To Data Out (3rd CL value): 		%d.%2d[ns]\n",+                                                  leftOfPoint, rightOfPoint );+                break;+/*----------------------------------------------------------------------------*/+    +            case 27: /* Minimum Row Precharge Time */+                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;+                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0xff : 0xfc;+                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0x00 : 0x03;+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;+                temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/+                trp_clocks = (temp + (busClkPs-1)) /  busClkPs;    +                mvOsOutput("Minimum Row Precharge Time [ns]: 		%d.%d = " +                           "in Clk cycles %d\n", +                           leftOfPoint, rightOfPoint, trp_clocks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 28: /* Minimum Row Active to Row Active Time */+                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;+                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0xff : 0xfc;+                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0x00 : 0x03;+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;+                temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/+                trrd_clocks = (temp + (busClkPs-1)) / busClkPs;+                mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: " +                           "%d.%d = in Clk cycles %d\n",+                            leftOfPoint, rightOfPoint, trp_clocks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 29: /* Minimum Ras-To-Cas Delay */+                shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;+                maskLeftOfPoint  = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0xff : 0xfc;+                maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? +                                                                    0x00 : 0x03;+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;  +                temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/+                trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;+                mvOsOutput("Minimum Ras-To-Cas Delay [ns]: 			%d.%d = "+                           "in Clk cycles %d\n", +                           leftOfPoint, rightOfPoint, trp_clocks);+                break;+/*----------------------------------------------------------------------------*/+   +            case 30: /* Minimum Ras Pulse Width */+                tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;+                mvOsOutput("Minimum Ras Pulse Width [ns]: 			%d = "+                           "in Clk cycles %d\n", spdRawData[i], tras_clocks);+                break;+/*----------------------------------------------------------------------------*/+    +            case 31: /* Module Bank Density */+                mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");++                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    if (dimmInfo.dimmBankDensity & BIT0)+                        mvOsOutput("1GB, ");+                    if (dimmInfo.dimmBankDensity & BIT1)+                        mvOsOutput("8MB, ");+                    if (dimmInfo.dimmBankDensity & BIT2)+                        mvOsOutput("16MB, ");+                    if (dimmInfo.dimmBankDensity & BIT3)+                        mvOsOutput("32MB, ");+                    if (dimmInfo.dimmBankDensity & BIT4)+                        mvOsOutput("64MB, ");+                    if (dimmInfo.dimmBankDensity & BIT5)+                        mvOsOutput("128MB, ");+                    if (dimmInfo.dimmBankDensity & BIT6) +                        mvOsOutput("256MB, ");+                    if (dimmInfo.dimmBankDensity & BIT7) +                        mvOsOutput("512MB, ");+                }+                else if (dimmInfo.memoryType == MEM_TYPE_DDR1)+                {+                    if (dimmInfo.dimmBankDensity & BIT0)+                        mvOsOutput("1GB, ");+                    if (dimmInfo.dimmBankDensity & BIT1)+                        mvOsOutput("2GB, ");+                    if (dimmInfo.dimmBankDensity & BIT2)+                        mvOsOutput("16MB, ");+                    if (dimmInfo.dimmBankDensity & BIT3)+                        mvOsOutput("32MB, ");+                    if (dimmInfo.dimmBankDensity & BIT4)+                        mvOsOutput("64MB, ");+                    if (dimmInfo.dimmBankDensity & BIT5)+                        mvOsOutput("128MB, ");+                    if (dimmInfo.dimmBankDensity & BIT6) +                        mvOsOutput("256MB, ");+                    if (dimmInfo.dimmBankDensity & BIT7) +                        mvOsOutput("512MB, ");+                }+                else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */+                {+                    if (dimmInfo.dimmBankDensity & BIT0)+                        mvOsOutput("1GB, ");+                    if (dimmInfo.dimmBankDensity & BIT1)+                        mvOsOutput("2GB, ");+                    if (dimmInfo.dimmBankDensity & BIT2)+                        mvOsOutput("4GB, ");+                    if (dimmInfo.dimmBankDensity & BIT3)+                        mvOsOutput("8GB, ");+                    if (dimmInfo.dimmBankDensity & BIT4)+                        mvOsOutput("16GB, ");+                    if (dimmInfo.dimmBankDensity & BIT5)+                    mvOsOutput("128MB, ");+                        if (dimmInfo.dimmBankDensity & BIT6) +                    mvOsOutput("256MB, ");+                        if (dimmInfo.dimmBankDensity & BIT7) +                    mvOsOutput("512MB, ");+                }+                mvOsOutput("\n");+                break;+/*----------------------------------------------------------------------------*/+    +            case 32: /* Address And Command Setup Time (measured in ns/1000) */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                    leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100; +                }+                mvOsOutput("Address And Command Setup Time [ns]: 		%d.%d\n",+                                                     leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 33: /* Address And Command Hold Time */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                    leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100;                 +                }+                mvOsOutput("Address And Command Hold Time [ns]: 		%d.%d\n",+                                                   leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 34: /* Data Input Setup Time */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                        leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100;                 +                }+                mvOsOutput("Data Input Setup Time [ns]: 			%d.%d\n", +                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 35: /* Data Input Hold Time */+                if (dimmInfo.memoryType == MEM_TYPE_SDRAM)+                {+                    rightOfPoint = (spdRawData[i] & 0x0f);+                    leftOfPoint  = (spdRawData[i] & 0xf0) >> 4;+                    if(leftOfPoint > 7)+                    {+                        leftOfPoint *= -1;+                    }+                }+                else /* DDR1 or DDR2 */+                {+                    time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) + +                                                      ((spdRawData[i] & 0x0f));+                    leftOfPoint = time_tmp / 100;+                    rightOfPoint = time_tmp % 100;                 +                }+                mvOsOutput("Data Input Hold Time [ns]: 			%d.%d\n\n", +                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+    +            case 36: /* Relevant for DDR2 only: Write Recovery Time */+                leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);+                rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;  +                mvOsOutput("Write Recovery Time [ns]: 			%d.%d\n", +                                                    leftOfPoint, rightOfPoint);+                break;+/*----------------------------------------------------------------------------*/+        }+    +}+++/*+ * translate ns.ns/10 coding of SPD timing values+ * into ps unit values+ */+/*******************************************************************************+*  cas2ps - Translate x.y ns parameter to pico-seconds values+*+* DESCRIPTION:+*       This function translates x.y nano seconds to its value in pico seconds.+*       For example 3.75ns will return 3750.+*+* INPUT:+*       spd_byte - DIMM SPD byte.+*+* OUTPUT:+*       None.+*+* RETURN:+*       value in pico seconds.+*+*******************************************************************************/+static MV_U32  cas2ps(MV_U8 spd_byte)+{+    MV_U32 ns, ns10;+    +    /* isolate upper nibble */+    ns = (spd_byte >> 4) & 0x0F;+    /* isolate lower nibble */+    ns10 = (spd_byte & 0x0F);+    +    if( ns10 < 10 ) {+        ns10 *= 10;+    }+    else if( ns10 == 10 )+        ns10 = 25;+    else if( ns10 == 11 )+        ns10 = 33;+    else if( ns10 == 12 )+        ns10 = 66;+    else if( ns10 == 13 )+        ns10 = 75;+    else +    {+        mvOsOutput("cas2ps Err. unsupported cycle time.\n");+    }+    +    return (ns*1000 + ns10*10);+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h	2010-11-09 20:28:11.032495447 +0100@@ -0,0 +1,192 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvDram+#define __INCmvDram++#include "ddr2/mvDramIf.h"+#include "twsi/mvTwsi.h"++#define MAX_DIMM_NUM 			2+#define SPD_SIZE			128++/* Dimm spd offsets */+#define DIMM_MEM_TYPE 					2+#define DIMM_ROW_NUM 					3+#define DIMM_COL_NUM 					4+#define DIMM_MODULE_BANK_NUM 				5+#define DIMM_DATA_WIDTH 				6+#define DIMM_VOLT_IF 					8+#define DIMM_MIN_CC_AT_MAX_CAS 				9+#define DIMM_ERR_CHECK_TYPE 				11+#define DIMM_REFRESH_INTERVAL 				12+#define DIMM_SDRAM_WIDTH 				13+#define DIMM_ERR_CHECK_DATA_WIDTH 			14+#define DIMM_MIN_CLK_DEL 				15+#define DIMM_BURST_LEN_SUP 				16+#define DIMM_DEV_BANK_NUM 				17+#define DIMM_SUP_CAL 					18+#define DIMM_DDR2_TYPE_INFORMATION          		20      /* DDR2 only */+#define DIMM_BUF_ADDR_CONT_IN 				21+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1			23+#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2			25+#define DIMM_MIN_ROW_PRECHARGE_TIME			27+#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE		28+#define DIMM_MIN_RAS_TO_CAS_DELAY			29+#define DIMM_MIN_RAS_PULSE_WIDTH			30+#define DIMM_BANK_DENSITY				31+#define DIMM_MIN_WRITE_RECOVERY_TIME        		36+#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY    		37+#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY    		38+#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD    		42+#define DIMM_SPD_VERSION    				62++/* Dimm Memory Type values */+#define DIMM_MEM_TYPE_SDRAM					0x4+#define DIMM_MEM_TYPE_DDR1 					0x7+#define DIMM_MEM_TYPE_DDR2 					0x8+        +#define DIMM_MODULE_MANU_OFFS 		64+#define DIMM_MODULE_MANU_SIZE 		8+#define DIMM_MODULE_VEN_OFFS 		73 +#define DIMM_MODULE_VEN_SIZE 		25+#define DIMM_MODULE_ID_OFFS 		99+#define DIMM_MODULE_ID_SIZE 		18++/* enumeration for voltage levels. */+typedef enum _mvDimmVoltageIf+{+    TTL_5V_TOLERANT, +    LVTTL, +    HSTL_1_5V, +    SSTL_3_3V, +    SSTL_2_5V, +    VOLTAGE_UNKNOWN, +} MV_DIMM_VOLTAGE_IF;+++/* enumaration for SDRAM CAS Latencies. */+typedef enum _mvDimmSdramCas+{+    SD_CL_1 =1,  +    SD_CL_2,  +    SD_CL_3, +    SD_CL_4, +    SD_CL_5, +    SD_CL_6, +    SD_CL_7, +    SD_FAULT+}MV_DIMM_SDRAM_CAS;+++/* DIMM information structure */                                                    +typedef struct _mvDimmInfo+{+    MV_MEMORY_TYPE  memoryType; 	/* DDR or SDRAM */++    MV_U8       spdRawData[SPD_SIZE];  	/* Content of SPD-EEPROM copied 1:1  */++    /* DIMM dimensions */+    MV_U32  numOfRowAddr;+    MV_U32  numOfColAddr;+    MV_U32  numOfModuleBanks;+    MV_U32  dataWidth;+    MV_U32  errorCheckType;             /* ECC , PARITY..*/+    MV_U32  sdramWidth;                 /* 4,8,16 or 32 */+    MV_U32  errorCheckDataWidth;        /* 0 - no, 1 - Yes */+    MV_U32  burstLengthSupported;+    MV_U32  numOfBanksOnEachDevice;+    MV_U32  suportedCasLatencies;+    MV_U32  refreshInterval;+    MV_U32  dimmBankDensity;+    MV_U32  dimmTypeInfo;           /* DDR2 only */+    MV_U32  dimmAttributes;++    /* DIMM timing parameters */+    MV_U32  minCycleTimeAtMaxCasLatPs;	+    MV_U32  minCycleTimeAtMaxCasLatMinus1Ps;+    MV_U32  minCycleTimeAtMaxCasLatMinus2Ps;+	MV_U32  minRowPrechargeTime;+	MV_U32  minRowActiveToRowActive;+	MV_U32  minRasToCasDelay;+	MV_U32  minRasPulseWidth;+    MV_U32  minWriteRecoveryTime;   /* DDR2 only */+    MV_U32  minWriteToReadCmdDelay; /* DDR2 only */+    MV_U32  minReadToPrechCmdDelay; /* DDR2 only */+    MV_U32  minRefreshToActiveCmd;  /* DDR2 only */++    /* Parameters calculated from the extracted DIMM information */+    MV_U32  size;               /* 16,64,128,256 or 512 MByte in MB units */+    MV_U32  deviceDensity;      /* 16,64,128,256 or 512 Mbit in MB units  */+    MV_U32  numberOfDevices;++} MV_DIMM_INFO;+++MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);+MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);+MV_VOID dimmSpdPrint(MV_U32 dimmNum);+MV_STATUS dimmSpdCpy(MV_VOID);++#endif /* __INCmvDram */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c	2010-11-09 20:28:11.042495489 +0100@@ -0,0 +1,2952 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/*******************************************************************************+* mvEth.c - Marvell's Gigabit Ethernet controller low level driver+*+* DESCRIPTION:+*       This file introduce OS independent APIs to Marvell's Gigabit Ethernet+*       controller. This Gigabit Ethernet Controller driver API controls+*       1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').+*       2) Data flow (i.e. port Send, Receive etc').+*       3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)+*       4) MIB counters support (ethReadMibCounter)+*       5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)+*       Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.+*       This struct includes configuration information as well as driver+*       internal data needed for its operations.+*+*       Supported Features:+*       - OS independent. All required OS services are implemented via external +*       OS dependent components (like osLayer or ethOsg)+*       - The user is free from Rx/Tx queue managing.+*       - Simple Gigabit Ethernet port operation API.+*       - Simple Gigabit Ethernet port data flow API.+*       - Data flow and operation API support per queue functionality.+*       - Support cached descriptors for better performance.+*       - PHY access and control API.+*       - Port Configuration API.+*       - Full control over Special and Other Multicast MAC tables.+*+*******************************************************************************/+/* includes */+#include "mvTypes.h"+#include "mv802_3.h"+#include "mvDebug.h"+#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "eth-phy/mvEthPhy.h"+#include "eth/mvEth.h"+#include "eth/gbe/mvEthGbe.h"+#include "cpu/mvCpu.h"++#ifdef INCLUDE_SYNC_BARR+#include "sys/mvCpuIf.h"+#endif++#ifdef MV_RT_DEBUG+#   define ETH_DEBUG+#endif+++/* locals */+MV_BOOL         ethDescInSram;+MV_BOOL         ethDescSwCoher;++/* This array holds the control structure of each port */+ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];++/* Ethernet Port Local routines */++static void    ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);++static void    ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);++static void    ethSetUcastTable(int portNo, int queue);++static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);+static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);+static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);++static void    ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);+static MV_U8*  ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size, +                                   MV_ULONG* pPhysAddr, MV_U32 *memHandle);++static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);++static void mvEthPortSgmiiConfig(int port);++++/******************************************************************************/+/*                      EthDrv Initialization functions                       */+/******************************************************************************/++/*******************************************************************************+* mvEthHalInit - Initialize the Giga Ethernet unit+*+* DESCRIPTION:+*       This function initialize the Giga Ethernet unit.+*       1) Configure Address decode windows of the unit+*       2) Set registers to HW default values. +*       3) Clear and Disable interrupts+*+* INPUT:  NONE+*+* RETURN: NONE+*+* NOTE: this function is called once in the boot process.+*******************************************************************************/+void    mvEthHalInit(void)+{+    int port;++    /* Init static data structures */+    for (port=0; port<MV_ETH_MAX_PORTS; port++)+    {+        ethPortCtrl[port] = NULL;+    }+    /* Power down all existing ports */+    for(port=0; port<mvCtrlEthMaxPortGet(); port++)+    {++#if defined (MV78200)+	    /* Skip ports mapped to another CPU*/+	if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))+	{+		    continue;+	}		+#endif++	/* Skip power down ports */+	if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;++        /* Disable Giga Ethernet Unit interrupts */+        MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);++        /* Clear ETH_UNIT_INTR_CAUSE_REG register */+        MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);++    }++    mvEthMemAttrGet(ðDescInSram, ðDescSwCoher);++#if defined(ETH_DESCR_IN_SRAM)+    if(ethDescInSram == MV_FALSE)+    {+        mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");+    }+#endif /* ETH_DESCR_IN_SRAM */+}++/*******************************************************************************+* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED) +*                       of of memory location for RX and TX descriptors.+*+* DESCRIPTION:+*       This function allocates memory for RX and TX descriptors.+*       - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.+*       - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.+*+* INPUT:+*   MV_BOOL* pIsSram - place of descriptors: +*                      MV_TRUE  - in SRAM+*                      MV_FALSE - in DRAM+*   MV_BOOL* pIsSwCoher - cache coherency of descriptors:+*                      MV_TRUE  - driver is responsible for cache coherency+*                      MV_FALSE - driver is not responsible for cache coherency+*+* RETURN:+*+*******************************************************************************/+void   mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)+{+    MV_BOOL isSram, isSwCoher;++    isSram = MV_FALSE;+#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) +    isSwCoher = MV_TRUE;+#else +    isSwCoher = MV_FALSE;+#endif++#if defined(ETH_DESCR_IN_SRAM)+    if( mvCtrlSramSizeGet() > 0)+    {+        isSram = MV_TRUE;+        #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW) +            isSwCoher = MV_TRUE;+        #else +            isSwCoher = MV_FALSE;+        #endif+    }+#endif /* ETH_DESCR_IN_SRAM */++    if(pIsSram != NULL)+        *pIsSram = isSram;++    if(pIsSwCoher != NULL)+        *pIsSwCoher = isSwCoher;+}++++/******************************************************************************/+/*                      Port Initialization functions                         */+/******************************************************************************/++/*******************************************************************************+* mvEthPortInit - Initialize the Ethernet port driver+*+* DESCRIPTION:+*       This function initialize the ethernet port.+*       1) Allocate and initialize internal port Control structure.+*       2) Create RX and TX descriptor rings for default RX and TX queues+*       3) Disable RX and TX operations, clear cause registers and +*          mask all interrupts.+*       4) Set all registers to default values and clean all MAC tables. +*+* INPUT:+*       int             portNo          - Ethernet port number+*       ETH_PORT_INIT   *pEthPortInit   - Ethernet port init structure+*+* RETURN:+*       void* - ethernet port handler, that should be passed to the most other+*               functions dealing with this port.+*+* NOTE: This function is called once per port when loading the eth module.+*******************************************************************************/+void*   mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)+{+    int             queue, descSize;+    ETH_PORT_CTRL*  pPortCtrl;++    /* Check validity of parameters */+    if( (portNo >= (int)mvCtrlEthMaxPortGet()) || +        (pEthPortInit->rxDefQ   >= MV_ETH_RX_Q_NUM)  ||+        (pEthPortInit->maxRxPktSize < 1518) )+    {+        mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);+        return NULL;+    }+    if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)+    {+        mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n", +                    portNo, pEthPortInit->rxDefQ);+        return NULL;+    }++    pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );+    if(pPortCtrl == NULL)   +    {+       mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",+                   (int)sizeof(ETH_PORT_CTRL), portNo);+       return NULL;+    }++    memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );+    ethPortCtrl[portNo] = pPortCtrl;++    pPortCtrl->portState = MV_UNDEFINED_STATE;++    pPortCtrl->portNo = portNo;++    pPortCtrl->osHandle = pEthPortInit->osHandle;++    /* Copy Configuration parameters */+    pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;+    pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;+    pPortCtrl->portConfig.ejpMode = 0;++    for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )+    {+        pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];+    }+    for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )+    {+        pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];+    }++    mvEthPortDisable(pPortCtrl);++    /* Set the board information regarding PHY address */+    mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );++    /* Create all requested RX queues */+    for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)+    {+        if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)+            continue;++        /* Allocate memory for RX descriptors */+        descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) ++                                                        CPU_D_CACHE_LINE_SIZE);+ +        pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr = +                        ethAllocDescrMemory(pPortCtrl, descSize, +					    &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,+					    &pPortCtrl->rxQueue[queue].descBuf.memHandle);+        pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;+        if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)+        {+            mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n", +                        pPortCtrl->portNo, queue, descSize, +                        ethDescInSram ? "SRAM" : "DRAM",+                        pPortCtrl->rxQueueConfig[queue].descrNum);+            return NULL;+        }++        ethInitRxDescRing(pPortCtrl, queue);+    }+    /* Create TX queues */+    for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)+    {+        if(pPortCtrl->txQueueConfig[queue].descrNum == 0)+            continue;++        /* Allocate memory for TX descriptors */+        descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) ++                                                        CPU_D_CACHE_LINE_SIZE);+ +        pPortCtrl->txQueue[queue].descBuf.bufVirtPtr = +		ethAllocDescrMemory(pPortCtrl, descSize,+				    &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,+				    &pPortCtrl->txQueue[queue].descBuf.memHandle);+        pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;+        if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)+        {+            mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n", +                        pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",+                        pPortCtrl->txQueueConfig[queue].descrNum);+            return NULL;+        }++        ethInitTxDescRing(pPortCtrl, queue);+    }+    mvEthDefaultsSet(pPortCtrl);++    pPortCtrl->portState = MV_IDLE;+    return pPortCtrl;+}++/*******************************************************************************+* ethPortFinish - Finish the Ethernet port driver+*+* DESCRIPTION:+*       This function finish the ethernet port.+*       1) Down ethernet port if needed.+*       2) Delete RX and TX descriptor rings for all created RX and TX queues+*       3) Free internal port Control structure.+*+* INPUT:+*       void*   pEthPortHndl  - Ethernet port handler+*+* RETURN:   NONE.+*+*******************************************************************************/+void    mvEthPortFinish(void* pPortHndl)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    int             queue, portNo  = pPortCtrl->portNo;++    if(pPortCtrl->portState == MV_ACTIVE)+    {+        mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",+                 portNo);+        mvEthPortDisable(pPortHndl);+    }++    /* Free all allocated RX queues */+    for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)+    {+        ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);+    }++    /* Free all allocated TX queues */+    for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)+    {+        ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);+    }++    /* Free port control structure */+    mvOsFree(pPortCtrl);++    ethPortCtrl[portNo] = NULL;+}++/*******************************************************************************+* mvEthDefaultsSet - Set defaults to the ethernet port+*+* DESCRIPTION:+*       This function set default values to the ethernet port.+*       1) Clear Cause registers and Mask all interrupts+*       2) Clear all MAC tables+*       3) Set defaults to all registers+*       4) Reset all created RX and TX descriptors ring+*       5) Reset PHY+*+* INPUT:+*       void*   pEthPortHndl  - Ethernet port handler+*+* RETURN:   MV_STATUS  +*               MV_OK - Success, Others - Failure+* NOTE:+*   This function update all the port configuration except those set+*   Initialy by the OsGlue by MV_ETH_PORT_INIT.+*   This function can be called after portDown to return the port setting +*   to defaults.+*******************************************************************************/+MV_STATUS   mvEthDefaultsSet(void* pPortHndl)+{+    int                 ethPortNo, queue;+    ETH_PORT_CTRL*      pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    ETH_QUEUE_CTRL*     pQueueCtrl;+    MV_U32              txPrio;+    MV_U32              portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;+    MV_BOARD_MAC_SPEED  boardMacCfg;++    ethPortNo = pPortCtrl->portNo;++    /* Clear Cause registers */+    MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);+    MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);++    /* Mask all interrupts */+    MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);+    MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);++    portCfgReg  =   PORT_CONFIG_VALUE;+    portCfgExtReg  =  PORT_CONFIG_EXTEND_VALUE;++    boardMacCfg = mvBoardMacSpeedGet(ethPortNo);++    if(boardMacCfg == BOARD_MAC_SPEED_100M)+    {+        portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;+    }+    else if(boardMacCfg == BOARD_MAC_SPEED_1000M)+    {+        portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;+    }+    else+    {+        portSerialCtrlReg =  PORT_SERIAL_CONTROL_VALUE;+    }++    /* build PORT_SDMA_CONFIG_REG */+    portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);+    portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);++#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) ||  \+      (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )+    /* some devices have restricted RX burst size when using HW coherency */+    portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);+#else+    portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);+#endif++#if defined(MV_CPU_BE)+    /* big endian */+# if defined(MV_ARM)+    portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |+                       ETH_TX_NO_DATA_SWAP_MASK |+                       ETH_DESC_SWAP_MASK);+# elif defined(MV_PPC)+    portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |+                       ETH_TX_DATA_SWAP_MASK |+                       ETH_NO_DESC_SWAP_MASK);+# else+# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"+# endif /* MV_ARM / MV_PPC */++#else /* MV_CPU_LE */+    /* little endian */+    portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK | +                       ETH_TX_NO_DATA_SWAP_MASK | +                       ETH_NO_DESC_SWAP_MASK);+#endif /* MV_CPU_BE / MV_CPU_LE */++    pPortCtrl->portRxQueueCmdReg = 0;+    pPortCtrl->portTxQueueCmdReg = 0;++#if (MV_ETH_VERSION >= 4) +    if(pPortCtrl->portConfig.ejpMode == MV_TRUE)+    {+        MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);+    }+    else+    {+        MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)+    }+#endif /* (MV_ETH_VERSION >= 4) */++    ethSetUcastTable(ethPortNo, -1);+    mvEthSetSpecialMcastTable(ethPortNo, -1);+    mvEthSetOtherMcastTable(ethPortNo, -1);++    portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;++    portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);++    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);++    /* Update value of PortConfig register accordingly with all RxQueue types */+    pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;+    pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ; +    pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ; +    pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ; ++    portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;+    portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);+    +    portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;+    portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ); ++    portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;+    portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);++    portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;+    portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);++    portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;+    portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);++    /* Assignment of Tx CTRP of given queue */+    txPrio = 0;++    for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)+    {+        pQueueCtrl = &pPortCtrl->txQueue[queue];++        if(pQueueCtrl->pFirstDescr != NULL)+        {+            ethResetTxDescRing(pPortCtrl, queue);++            MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),+                         0x3fffffff);+            MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), +                         0x03ffffff);+        }+        else+        {+            MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),  0x0);+            MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);+        }+    }++    /* Assignment of Rx CRDP of given queue */+    for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)+    {+        ethResetRxDescRing(pPortCtrl, queue);+    }++    /* Allow receiving packes with odd number of preamble nibbles */+    portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));+    portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);++    /* Assign port configuration and command. */+    MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);++    MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);++    /* Assign port SDMA configuration */+    MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);+    +    /* Turn off the port/queue bandwidth limitation */+    MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);++    return MV_OK;+}++/*******************************************************************************+* ethPortUp - Start the Ethernet port RX and TX activity.+*+* DESCRIPTION:+*       This routine start Rx and Tx activity:+*+*       Note: Each Rx and Tx queue descriptor's list must be initialized prior+*       to calling this function (use etherInitTxDescRing for Tx queues and+*       etherInitRxDescRing for Rx queues).+*+* INPUT:+*       void*   pEthPortHndl  - Ethernet port handler+*+* RETURN:   MV_STATUS+*           MV_OK - Success, Others - Failure.+*+* NOTE : used for port link up.+*******************************************************************************/+MV_STATUS   mvEthPortUp(void* pEthPortHndl)+{+    int             ethPortNo;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;++    ethPortNo = pPortCtrl->portNo;+    +    if( (pPortCtrl->portState != MV_ACTIVE) && +        (pPortCtrl->portState != MV_PAUSED) )+    {+        mvOsPrintf("ethDrv port%d: Unexpected port state %d\n", +                        ethPortNo, pPortCtrl->portState);+        return MV_BAD_STATE;+    }+    +    ethPortNo = pPortCtrl->portNo;++    /* Enable port RX. */+    MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);++    /* Enable port TX. */+    MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;++    pPortCtrl->portState = MV_ACTIVE;++    return MV_OK;+}++/*******************************************************************************+* ethPortDown - Stop the Ethernet port activity.+*+* DESCRIPTION:+*+* INPUT:+*       void*   pEthPortHndl  - Ethernet port handler+*+* RETURN:   MV_STATUS+*               MV_OK - Success, Others - Failure.+*+* NOTE : used for port link down.+*******************************************************************************/+MV_STATUS   mvEthPortDown(void* pEthPortHndl)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    int             ethPortNum = pPortCtrl->portNo;+    unsigned int    regData;+    volatile int    uDelay, mDelay;++    /* Stop Rx port activity. Check port Rx activity. */+    regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;+    if(regData != 0)+    {+        /* Issue stop command for active channels only */+        MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));+    }++    /* Stop Tx port activity. Check port Tx activity. */+    regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;+    if(regData != 0)+    {+        /* Issue stop command for active channels only */+        MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum), +                            (regData << ETH_TXQ_DISABLE_OFFSET) ); +    }++    /* Force link down */+/*+    regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));+    regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);+*/+    /* Wait for all Rx activity to terminate. */+    mDelay = 0;+    do+    {+        if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)+        {+            mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n", +                        ethPortNum, regData);+            break;+        }+        mvOsDelay(1);+        mDelay++;+        +        /* Check port RX Command register that all Rx queues are stopped */+        regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));+    }+    while(regData & 0xFF);++    /* Wait for all Tx activity to terminate. */+    mDelay = 0;+    do+    {+        if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)+        {+            mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n", +                        ethPortNum, regData);+            break;+        }+        mvOsDelay(1);+        mDelay++;++        /* Check port TX Command register that all Tx queues are stopped */+        regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));+    }+    while(regData & 0xFF);+    +    /* Double check to Verify that TX FIFO is Empty */+    mDelay = 0;+    while(MV_TRUE)+    {+        do+        {+            if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)+            {+                mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n", +                            ethPortNum, regData);+                break;+            }+            mvOsDelay(1);+            mDelay++;++            regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));+        }+        while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) || +               ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );++        if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)+            break;++        /* Double check */+        regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));+        if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) && +            ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )+        {+            break;+        }+        else+            mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",+                                ethPortNum, mDelay, regData);     +    }++    /* Do NOT force link down */+/*+    regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));+    regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);+*/+    /* Wait about 2500 tclk cycles */+    uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));+    mvOsUDelay(uDelay);++    pPortCtrl->portState = MV_PAUSED;++    return MV_OK;   +}+++/*******************************************************************************+* ethPortEnable - Enable the Ethernet port and Start RX and TX.+*+* DESCRIPTION:+*       This routine enable the Ethernet port and Rx and Tx activity:+*+*       Note: Each Rx and Tx queue descriptor's list must be initialized prior+*       to calling this function (use etherInitTxDescRing for Tx queues and+*       etherInitRxDescRing for Rx queues).+*+* INPUT:+*       void*   pEthPortHndl  - Ethernet port handler+*+* RETURN:   MV_STATUS+*               MV_OK - Success, Others - Failure.+*+* NOTE: main usage is to enable the port after ifconfig up.+*******************************************************************************/+MV_STATUS   mvEthPortEnable(void* pEthPortHndl)+{+    int             ethPortNo;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    MV_U32      portSerialCtrlReg;++    ethPortNo = pPortCtrl->portNo;++    /* Enable port */+    portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));+    portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);++    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);++    mvEthMibCountersClear(pEthPortHndl);++    pPortCtrl->portState = MV_PAUSED;++    /* If Link is UP, Start RX and TX traffic */+    if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)+        return( mvEthPortUp(pEthPortHndl) );+    +    return MV_NOT_READY;+}+++/*******************************************************************************+* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.+*+* DESCRIPTION:+*+* INPUT:+*       void*   pEthPortHndl  - Ethernet port handler+*+* RETURN:   MV_STATUS+*               MV_OK - Success, Others - Failure.+*+* NOTE: main usage is to disable the port after ifconfig down.+*******************************************************************************/+MV_STATUS   mvEthPortDisable(void* pEthPortHndl)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    int             ethPortNum = pPortCtrl->portNo;+    unsigned int    regData;+    volatile int    mvDelay;++    if(pPortCtrl->portState == MV_ACTIVE)           +    {    +        /* Stop RX and TX activities */+        mvEthPortDown(pEthPortHndl);+    }++    /* Reset the Enable bit in the Serial Control Register */+    regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));+    regData &= ~(ETH_PORT_ENABLE_MASK);+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);++    /* Wait about 2500 tclk cycles */+    mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));+    for(mvDelay; mvDelay>0; mvDelay--);++    pPortCtrl->portState = MV_IDLE;+    return MV_OK;+}++/*******************************************************************************+* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.+*+* DESCRIPTION:+*       This routine used to free buffers attached to the Tx ring and should+*       be called only when Giga Ethernet port is Down+*+* INPUT:+*       void*       pEthPortHndl    - Ethernet Port handler.+*       int         txQueue         - Number of TX queue.+*+* OUTPUT:+*       MV_PKT_INFO *pPktInfo       - Pointer to packet was sent.+*+* RETURN:+*       MV_EMPTY    - There is no more buffers in this queue.+*       MV_OK       - Buffer detached from the queue and pPktInfo structure +*                   filled with relevant information.+*+*******************************************************************************/+MV_PKT_INFO*    mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl;+    MV_PKT_INFO*    pPktInfo;+    ETH_TX_DESC*    pTxDesc;+    int             port = pPortCtrl->portNo;+       +    pQueueCtrl = &pPortCtrl->txQueue[txQueue];++    while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||+           (pQueueCtrl->resource == 0) )+    {+        /* Free next descriptor */+        pQueueCtrl->resource++;+        pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;++	/* pPktInfo is available only in descriptors which are last descriptors */+        pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;+	if (pPktInfo)+        	pPktInfo->status = pTxDesc->cmdSts;++        pTxDesc->cmdSts = 0x0;+        pTxDesc->returnInfo = 0x0;+        ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);++        pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);++        if (pPktInfo)+		if (pPktInfo->status  & ETH_TX_LAST_DESC_MASK) +            		return pPktInfo;+    }   +    MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue), +                    (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );+    return NULL;+}++        ++/*******************************************************************************+* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.+*+* DESCRIPTION:+*       This routine used to free buffers attached to the Rx ring and should+*       be called only when Giga Ethernet port is Down+*+* INPUT:+*       void*       pEthPortHndl    - Ethernet Port handler.+*       int         rxQueue         - Number of Rx queue.+*+* OUTPUT:+*       MV_PKT_INFO *pPktInfo       - Pointer to received packet.+*+* RETURN:+*       MV_EMPTY    - There is no more buffers in this queue.+*       MV_OK       - Buffer detached from the queue and pBufInfo structure +*                   filled with relevant information.+*+*******************************************************************************/+MV_PKT_INFO*    mvEthPortForceRx(void* pEthPortHndl, int rxQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl;+    ETH_RX_DESC*    pRxDesc;+    MV_PKT_INFO*    pPktInfo;+    int             port = pPortCtrl->portNo;+       +    pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];++    if(pQueueCtrl->resource == 0)+    {+        MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue), +                    (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );++        return NULL;+    }+    /* Free next descriptor */+    pQueueCtrl->resource--;+    pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;+    pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;++    pPktInfo->status  = pRxDesc->cmdSts;+    pRxDesc->cmdSts = 0x0;+    pRxDesc->returnInfo = 0x0;+    ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);++    pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);+    return pPktInfo;    +}+++/******************************************************************************/+/*                          Port Configuration functions                      */+/******************************************************************************/+/*******************************************************************************+* mvEthMruGet - Get MRU configuration for Max Rx packet size.+*+* INPUT:+*           MV_U32 maxRxPktSize - max  packet size.+*+* RETURN:   MV_U32 - MRU configuration.+*+*******************************************************************************/+static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)+{+    MV_U32 portSerialCtrlReg = 0;++    if(maxRxPktSize > 9192)+        portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;+    else if(maxRxPktSize > 9022)+        portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;+    else if(maxRxPktSize > 1552)+        portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;+    else if(maxRxPktSize > 1522)+        portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;+    else if(maxRxPktSize > 1518)+        portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;+    else+        portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;++    return portSerialCtrlReg;+}++/*******************************************************************************+* mvEthRxCoalSet  - Sets coalescing interrupt mechanism on RX path+*+* DESCRIPTION:+*       This routine sets the RX coalescing interrupt mechanism parameter.+*       This parameter is a timeout counter, that counts in 64 tClk+*       chunks, that when timeout event occurs a maskable interrupt occurs.+*       The parameter is calculated using the tCLK frequency of the+*       MV-64xxx chip, and the required number is in micro seconds.+*+* INPUT:+*       void*           pPortHndl   - Ethernet Port handler.+*       MV_U32          uSec        - Number of micro seconds between +*                                   RX interrupts+*+* RETURN:+*       None.+*+* COMMENT:     +*   1 sec           - TCLK_RATE clocks+*   1 uSec          - TCLK_RATE / 1,000,000 clocks+*+*   Register Value for N micro seconds -  ((N * ( (TCLK_RATE / 1,000,000)) / 64)+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_U32    mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec) +{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    MV_U32          coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);+    MV_U32          portSdmaCfgReg;++    portSdmaCfgReg =  MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));+    portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;++    portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);++#if (MV_ETH_VERSION >= 2)+    /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */+    if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)+        portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;+#endif /* MV_ETH_VERSION >= 2 */++    MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);+    return coal;+}++/*******************************************************************************+* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path+*+* DESCRIPTION:+*       This routine sets the TX coalescing interrupt mechanism parameter.+*       This parameter is a timeout counter, that counts in 64 tClk+*       chunks, that when timeout event occurs a maskable interrupt+*       occurs.+*       The parameter is calculated using the tCLK frequency of the+*       MV-64xxx chip, and the required number is in micro seconds.+*+* INPUT:+*       void*           pPortHndl    - Ethernet Port handler.+*       MV_U32          uSec        - Number of micro seconds between +*                                   RX interrupts+*+* RETURN:+*       None.+*+* COMMENT:     +*   1 sec           - TCLK_RATE clocks+*   1 uSec          - TCLK_RATE / 1,000,000 clocks+*+*   Register Value for N micro seconds -  ((N * ( (TCLK_RATE / 1,000,000)) / 64)+*+*******************************************************************************/+MV_U32    mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec) +{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    MV_U32          coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);+    MV_U32          regVal;++    regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));+    regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;+    regVal |= ETH_TX_INTR_COAL_MASK(coal);++    /* Set TX Coalescing mechanism */+    MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal); +    return coal;+}++/*******************************************************************************+* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds+*+* DESCRIPTION:+*       This routine gets the RX and TX coalescing interrupt values.+*       The parameter is calculated using the tCLK frequency of the+*       MV-64xxx chip, and the returned numbers are in micro seconds.+*+* INPUTs:+*       void*   pPortHndl   - Ethernet Port handler.+*+* OUTPUTs:+*       MV_U32* pRxCoal     - Number of micro seconds between RX interrupts+*       MV_U32* pTxCoal     - Number of micro seconds between TX interrupts+*+* RETURN:+*       MV_STATUS   MV_OK  - success+*                   Others - failure.+*+* COMMENT:     +*   1 sec           - TCLK_RATE clocks+*   1 uSec          - TCLK_RATE / 1,000,000 clocks+*+*   Register Value for N micro seconds -  ((N * ( (TCLK_RATE / 1,000,000)) / 64)+*+*******************************************************************************/+MV_STATUS   mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)+{+    MV_U32  regVal, coal, usec;++    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    /* get TX Coalescing */+    regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));+    coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);++    usec = (coal * 64) / (mvBoardTclkGet() / 1000000);+    if(pTxCoal != NULL)+        *pTxCoal = usec;++    /* Get RX Coalescing */+    regVal =  MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));+    coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);++#if (MV_ETH_VERSION >= 2)+    if(regVal & ETH_RX_INTR_COAL_MSB_MASK)+    {+        /* Add MSB */+        coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);+    }+#endif /* MV_ETH_VERSION >= 2 */++    usec = (coal * 64) / (mvBoardTclkGet() / 1000000);+    if(pRxCoal != NULL)+        *pRxCoal = usec;++    return MV_OK;+}++/*******************************************************************************+* mvEthMaxRxSizeSet - +*+* DESCRIPTION:+*       Change maximum receive size of the port. This configuration will take place +*       after next call of ethPortSetDefaults() function.+*+* INPUT:+*+* RETURN:+*******************************************************************************/+MV_STATUS   mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    MV_U32      portSerialCtrlReg;++    if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))+       return MV_BAD_PARAM;+    +    pPortCtrl->portConfig.maxRxPktSize = maxRxSize;++    portSerialCtrlReg =  MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));+    portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;+    portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);++    return MV_OK;+}+++/******************************************************************************/+/*                      MAC Filtering functions                               */+/******************************************************************************/++/*******************************************************************************+* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port+*+* DESCRIPTION:+*       This routine used to free buffers attached to the Rx ring and should+*       be called only when Giga Ethernet port is Down+*+* INPUT:+*       void*       pEthPortHndl    - Ethernet Port handler.+*       MV_BOOL     isPromisc       - Promiscous mode+*                                   MV_TRUE  - accept all Broadcast, Multicast +*                                              and Unicast packets+*                                   MV_FALSE - accept all Broadcast, +*                                              specially added Multicast and+*                                              single Unicast packets+*+* RETURN:   MV_STATUS   MV_OK - Success, Other - Failure+*+*******************************************************************************/+MV_STATUS   mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    int             queue;+    MV_U32      portCfgReg;++    portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));+    /* Set / Clear UPM bit in port configuration register */+    if(isPromisc)+    {+        /* Accept all multicast packets to RX default queue */+        queue = pPortCtrl->portConfig.rxDefQ;+        portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;+        memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));+        MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);+        MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);+    }+    else+    {+        /* Reject all Multicast addresses */+        queue = -1;+        portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;+        /* Clear all mcastCount */+        memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));+    }+    MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);        ++    /* Set Special Multicast and Other Multicast tables */+    mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);+    mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);+    ethSetUcastTable(pPortCtrl->portNo, queue);++    return MV_OK;+}++/*******************************************************************************+* mvEthMacAddrSet - This function Set the port Unicast address.+*+* DESCRIPTION:+*       This function Set the port Ethernet MAC address. This address+*       will be used to send Pause frames if enabled. Packets with this+*       address will be accepted and dispatched to default RX queue+*+* INPUT:+*       void*   pEthPortHndl    - Ethernet port handler.+*       char*   pAddr           - Address to be set+*+* RETURN:   MV_STATUS+*               MV_OK - Success,  Other - Faulure+*+*******************************************************************************/+MV_STATUS   mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    unsigned int    macH;+    unsigned int    macL;++    if(queue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);+        return MV_BAD_PARAM;+    }++    if(queue != -1)+    {+        macL =  (pAddr[4] << 8) | (pAddr[5]);+        macH =  (pAddr[0] << 24)| (pAddr[1] << 16) |+                (pAddr[2] << 8) | (pAddr[3] << 0);++        MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),  macL);+        MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);+    }++    /* Accept frames of this address */+    ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);++    return MV_OK;+}++/*******************************************************************************+* mvEthMacAddrGet - This function returns the port Unicast address.+*+* DESCRIPTION:+*       This function returns the port Ethernet MAC address.+*+* INPUT:+*       int     portNo          - Ethernet port number.+*       char*   pAddr           - Pointer where address will be written to+*+* RETURN:   MV_STATUS+*               MV_OK - Success,  Other - Faulure+*+*******************************************************************************/+MV_STATUS   mvEthMacAddrGet(int portNo, unsigned char *pAddr)+{+    unsigned int    macH;+    unsigned int    macL;++    if(pAddr == NULL)+    {+        mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");+        return MV_BAD_PARAM;+    }++    macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));+    macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));+    pAddr[0] = (macH >> 24) & 0xff;+    pAddr[1] = (macH >> 16) & 0xff;+    pAddr[2] = (macH >> 8) & 0xff;+    pAddr[3] = macH  & 0xff;+    pAddr[4] = (macL >> 8) & 0xff;+    pAddr[5] = macL  & 0xff;++    return MV_OK;+}++/*******************************************************************************+* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.+*+* DESCRIPTION:+*+* INPUT:+*       MV_U8*  pAddr           - Address to calculate CRC-8+*+* RETURN: MV_U8 - CRC-8 of this MAC address+*+*******************************************************************************/+MV_U8   mvEthMcastCrc8Get(MV_U8* pAddr)+{+    unsigned int    macH;+    unsigned int    macL;+    int             macArray[48];+    int             crc[8];+    int             i;+    unsigned char   crcResult = 0;++        /* Calculate CRC-8 out of the given address */+    macH =  (pAddr[0] << 8) | (pAddr[1]);+    macL =  (pAddr[2] << 24)| (pAddr[3] << 16) |+            (pAddr[4] << 8) | (pAddr[5] << 0);++    for(i=0; i<32; i++)+        macArray[i] = (macL >> i) & 0x1;++    for(i=32; i<48; i++)+        macArray[i] = (macH >> (i - 32)) & 0x1;++    crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^+             macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^+             macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^+             macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^+             macArray[8]  ^ macArray[7]  ^ macArray[6]  ^ macArray[0];++    crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^+             macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^+             macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^+             macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^+             macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^+             macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^+             macArray[9]  ^ macArray[6]  ^ macArray[1]  ^ macArray[0];++    crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^+             macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^+             macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^+             macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^+             macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8]  ^+             macArray[6]  ^ macArray[2]  ^ macArray[1]  ^ macArray[0];++    crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^+             macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^+             macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^+             macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^+             macArray[13] ^ macArray[11] ^ macArray[9]  ^ macArray[7]  ^+             macArray[3]  ^ macArray[2]  ^ macArray[1];++    crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^+             macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^+             macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^+             macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^+             macArray[12] ^ macArray[10] ^ macArray[8]  ^ macArray[4]  ^+             macArray[3]  ^ macArray[2];++    crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^+             macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^+             macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^+             macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^+             macArray[13] ^ macArray[11] ^ macArray[9]  ^ macArray[5]  ^+             macArray[4]  ^ macArray[3];++    crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^+             macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^+             macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^+             macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^+             macArray[12] ^ macArray[10] ^ macArray[6]  ^ macArray[5]  ^+             macArray[4];++    crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^+             macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^+             macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^+             macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^+             macArray[11] ^ macArray[7]  ^ macArray[6]  ^ macArray[5];++    for(i=0; i<8; i++)+        crcResult = crcResult | (crc[i] << i);++    return crcResult;+}+/*******************************************************************************+* mvEthMcastAddrSet - Multicast address settings.+*+* DESCRIPTION:+*       This API controls the MV device MAC multicast support.+*       The MV device supports multicast using two tables:+*       1) Special Multicast Table for MAC addresses of the form+*          0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).+*          The MAC DA[7:0] bits are used as a pointer to the Special Multicast+*          Table entries in the DA-Filter table.+*          In this case, the function calls ethPortSmcAddr() routine to set the+*          Special Multicast Table.+*       2) Other Multicast Table for multicast of another type. A CRC-8bit+*          is used as an index to the Other Multicast Table entries in the+*          DA-Filter table.+*          In this case, the function calculates the CRC-8bit value and calls+*          ethPortOmcAddr() routine to set the Other Multicast Table.+*+* INPUT:+*       void*   pEthPortHndl    - Ethernet port handler.+*       MV_U8*  pAddr           - Address to be set+*       int     queue           - RX queue to capture all packets with this +*                               Multicast MAC address.+*                               -1 means delete this Multicast address.+*+* RETURN: MV_STATUS+*       MV_TRUE - Success, Other - Failure+*+*******************************************************************************/+MV_STATUS   mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    unsigned char   crcResult = 0;++    if(queue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethPort %d: RX queue #%d is out of range\n", +                    pPortCtrl->portNo, queue);+        return MV_BAD_PARAM;+    }++    if((pAddr[0] == 0x01) &&+       (pAddr[1] == 0x00) &&+       (pAddr[2] == 0x5E) &&+       (pAddr[3] == 0x00) &&+       (pAddr[4] == 0x00))+    {+        ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);+    }+    else+    {+        crcResult = mvEthMcastCrc8Get(pAddr);++        /* Check Add counter for this CRC value */+        if(queue == -1)+        {+            if(pPortCtrl->mcastCount[crcResult] == 0)+            {+                mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",+                            pPortCtrl->portNo, (unsigned)crcResult);+                return MV_NO_SUCH;+            }++            pPortCtrl->mcastCount[crcResult]--;+            if(pPortCtrl->mcastCount[crcResult] != 0)+            {+                mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",+                            pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],+                            (unsigned)crcResult);+                return MV_NO_CHANGE;+            }+        }+        else+        {+            pPortCtrl->mcastCount[crcResult]++;+            if(pPortCtrl->mcastCount[crcResult] > 1)+            {+                mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",+                                pPortCtrl->portNo, (unsigned)crcResult);+                return MV_NO_CHANGE;+            }+        }+        ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);+    }+    return MV_OK;+}++/*******************************************************************************+* ethSetUcastTable - Unicast address settings.+*+* DESCRIPTION:+*      Set all entries in the Unicast MAC Table queue==-1 means reject all +* INPUT:+*+* RETURN: +*+*******************************************************************************/+static void    ethSetUcastTable(int portNo, int queue)+{+    int     offset;+    MV_U32  regValue;++    if(queue == -1)+    {+        regValue = 0;+    }+    else+    {+        regValue = (((0x01 | (queue<<1)) << 0)  |+                    ((0x01 | (queue<<1)) << 8)  |+                    ((0x01 | (queue<<1)) << 16) |+                    ((0x01 | (queue<<1)) << 24));+    }++    for (offset=0; offset<=0xC; offset+=4)+        MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);+}++/*******************************************************************************+* mvEthSetSpecialMcastTable - Special Multicast address settings.+*+* DESCRIPTION:+*   Set all entries to the Special Multicast MAC Table. queue==-1 means reject all+* INPUT:+*+* RETURN: +*+*******************************************************************************/+MV_VOID    mvEthSetSpecialMcastTable(int portNo, int queue)+{+    int     offset;+    MV_U32  regValue;++    if(queue == -1)+    {+        regValue = 0;+    }+    else+    {+        regValue = (((0x01 | (queue<<1)) << 0)  |+                    ((0x01 | (queue<<1)) << 8)  |+                    ((0x01 | (queue<<1)) << 16) |+                    ((0x01 | (queue<<1)) << 24));+    }++    for (offset=0; offset<=0xFC; offset+=4)+    {+        MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) + +                      offset), regValue);+    }+}++/*******************************************************************************+* mvEthSetOtherMcastTable - Other Multicast address settings.+*+* DESCRIPTION:+*   Set all entries to the Other Multicast MAC Table. queue==-1 means reject all+* INPUT:+*+* RETURN: +*+*******************************************************************************/+MV_VOID    mvEthSetOtherMcastTable(int portNo, int queue)+{+    int     offset;+    MV_U32  regValue;++    if(queue == -1)+    {+        regValue = 0;+    }+    else+    {+        regValue = (((0x01 | (queue<<1)) << 0)  |+                    ((0x01 | (queue<<1)) << 8)  |+                    ((0x01 | (queue<<1)) << 16) |+                    ((0x01 | (queue<<1)) << 24));+    }++    for (offset=0; offset<=0xFC; offset+=4)+    {+        MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) + +                      offset), regValue);+    }+}++/*******************************************************************************+* ethSetUcastAddr - This function Set the port unicast address table+*+* DESCRIPTION:+*       This function locates the proper entry in the Unicast table for the+*       specified MAC nibble and sets its properties according to function+*       parameters.+*+* INPUT:+*       int     ethPortNum  - Port number.+*       MV_U8   lastNibble  - Unicast MAC Address last nibble.+*       int     queue       - Rx queue number for this MAC address.+*                           value "-1" means remove address+*+* OUTPUT:+*       This function add/removes MAC addresses from the port unicast address+*       table.+*+* RETURN:+*       MV_TRUE is output succeeded.+*       MV_FALSE if option parameter is invalid.+*+*******************************************************************************/+static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)+{+    unsigned int unicastReg;+    unsigned int tblOffset;+    unsigned int regOffset;++    /* Locate the Unicast table entry */+    lastNibble  = (0xf & lastNibble);+    tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/+    regOffset = lastNibble % 4;     /* Entry offset within the above register */+++    unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) + +                               tblOffset));+                 ++    if(queue == -1)+    {+        /* Clear accepts frame bit at specified unicast DA table entry */+        unicastReg &= ~(0xFF << (8*regOffset));+    }+    else+    {+        unicastReg &= ~(0xFF << (8*regOffset));+        unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));+    }+    MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),+                  unicastReg);++    return MV_TRUE;+}++/*******************************************************************************+* ethSetSpecialMcastAddr - Special Multicast address settings.+*+* DESCRIPTION:+*       This routine controls the MV device special MAC multicast support.+*       The Special Multicast Table for MAC addresses supports MAC of the form+*       0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).+*       The MAC DA[7:0] bits are used as a pointer to the Special Multicast+*       Table entries in the DA-Filter table.+*       This function set the Special Multicast Table appropriate entry+*       according to the argument given.+*+* INPUT:+*       int     ethPortNum      Port number.+*       unsigned char   mcByte      Multicast addr last byte (MAC DA[7:0] bits).+*       int          queue      Rx queue number for this MAC address.+*       int             option      0 = Add, 1 = remove address.+*+* OUTPUT:+*       See description.+*+* RETURN:+*       MV_TRUE is output succeeded.+*       MV_FALSE if option parameter is invalid.+*+*******************************************************************************/+static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)+{+    unsigned int smcTableReg;+    unsigned int tblOffset;+    unsigned int regOffset;++    /* Locate the SMC table entry */+    tblOffset = (lastByte / 4);     /* Register offset from SMC table base    */+    regOffset = lastByte % 4;       /* Entry offset within the above register */++    smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));+    +    if(queue == -1)+    {+        /* Clear accepts frame bit at specified Special DA table entry */+        smcTableReg &= ~(0xFF << (8 * regOffset));+    }+    else+    {+        smcTableReg &= ~(0xFF << (8 * regOffset));+        smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));+    }+    MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + +                  tblOffset*4), smcTableReg);++    return MV_TRUE;+}++/*******************************************************************************+* ethSetOtherMcastAddr - Multicast address settings.+*+* DESCRIPTION:+*       This routine controls the MV device Other MAC multicast support.+*       The Other Multicast Table is used for multicast of another type.+*       A CRC-8bit is used as an index to the Other Multicast Table entries+*       in the DA-Filter table.+*       The function gets the CRC-8bit value from the calling routine and+*       set the Other Multicast Table appropriate entry according to the+*       CRC-8 argument given.+*+* INPUT:+*       int     ethPortNum  Port number.+*       MV_U8   crc8        A CRC-8bit (Polynomial: x^8+x^2+x^1+1).+*       int     queue       Rx queue number for this MAC address.+*+* OUTPUT:+*       See description.+*+* RETURN:+*       MV_TRUE is output succeeded.+*       MV_FALSE if option parameter is invalid.+*+*******************************************************************************/+static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)+{+    unsigned int omcTableReg;+    unsigned int tblOffset;+    unsigned int regOffset;++    /* Locate the OMC table entry */+    tblOffset = (crc8 / 4) * 4;     /* Register offset from OMC table base    */+    regOffset = crc8 % 4;           /* Entry offset within the above register */++    omcTableReg = MV_REG_READ(+        (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));++    if(queue == -1)+    {+        /* Clear accepts frame bit at specified Other DA table entry */+        omcTableReg &= ~(0xFF << (8 * regOffset));+    }+    else+    {+        omcTableReg &= ~(0xFF << (8 * regOffset));+        omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));+    }++    MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset), +                    omcTableReg);++    return MV_TRUE;+}+++/******************************************************************************/+/*                      MIB Counters functions                                */+/******************************************************************************/+++/*******************************************************************************+* mvEthMibCounterRead - Read a MIB counter+*+* DESCRIPTION:+*       This function reads a MIB counter of a specific ethernet port.+*       NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or +*              ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,+*              so pHigh32 pointer should not be NULL in this case.+*+* INPUT:+*       int           ethPortNum  - Ethernet Port number.+*       unsigned int  mibOffset   - MIB counter offset.+*+* OUTPUT:+*       MV_U32*       pHigh32 - pointer to place where 32 most significant bits+*                             of the counter will be stored.+*+* RETURN:+*       32 low sgnificant bits of MIB counter value.+*+*******************************************************************************/+MV_U32  mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset, +                            MV_U32* pHigh32)+{+    int             portNo;+    MV_U32          valLow32, valHigh32;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;++    portNo = pPortCtrl->portNo;++    valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);+    +    /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits    */+    /* of a 64-bit MIB Counter.                                             */+    if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) || +        (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )+    {+        valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);+        if(pHigh32 != NULL)+            *pHigh32 = valHigh32;+    }+    return valLow32;+}++/*******************************************************************************+* mvEthMibCountersClear - Clear all MIB counters+*+* DESCRIPTION:+*       This function clears all MIB counters+*+* INPUT:+*       int           ethPortNum  - Ethernet Port number.+*+*+* RETURN:   void+*+*******************************************************************************/+void  mvEthMibCountersClear(void* pPortHandle)+{+    int             i, portNo;+    unsigned int    dummy;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;++    portNo = pPortCtrl->portNo;++    /* Perform dummy reads from MIB counters */+    for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)+        dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));+}+    ++/******************************************************************************/+/*                        RX Dispatching configuration routines               */+/******************************************************************************/++int     mvEthTosToRxqGet(void* pPortHandle, int tos)+{+    MV_U32          regValue;+    int             regIdx, regOffs, rxq;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;++    if(tos > 0xFF)+    {+        mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);+        return -1;+    }+    regIdx  = mvOsDivide(tos>>2, 10);+    regOffs = mvOsReminder(tos>>2, 10);+    +    regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );+    rxq = (regValue >> (regOffs*3));+    rxq &= 0x7;++    return rxq;+}++/*******************************************************************************+* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue+*+* DESCRIPTION:+*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*       int     tos         - TOS value in the IP header of the packet+*       int     rxq         - RX Queue for packets with the configured TOS value+*                           Negative value (-1) means no special processing for these packets, +*                           so they will be processed as regular packets.+*+* RETURN:   MV_STATUS+*******************************************************************************/+MV_STATUS   mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)+{+    MV_U32          regValue;+    int             regIdx, regOffs;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;++    if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )+    {+        mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);+        return MV_BAD_PARAM;+    }+    if(tos > 0xFF)+    {+        mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);+        return MV_BAD_PARAM;+    }+    regIdx  = mvOsDivide(tos>>2, 10);+    regOffs = mvOsReminder(tos>>2, 10);+    +    regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );+    regValue &= ~(0x7 << (regOffs*3));+    regValue |= (rxq << (regOffs*3));++    MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);+    return MV_OK;+}++/*******************************************************************************+* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with +*                        special priority bits [0-2]+*+* DESCRIPTION:+*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*       int     bpduQueue   - Special queue to capture VLAN tagged packets with special+*                           priority.+*                           Negative value (-1) means no special processing for these packets, +*                           so they will be processed as regular packets.+*+* RETURN:   MV_STATUS+*       MV_OK       - Success+*       MV_FAIL     - Failed. +*+*******************************************************************************/+MV_STATUS   mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    MV_U32          vlanPrioReg;++    if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);+        return MV_BAD_PARAM;+    }+    if(vlanPrio >= 8)+    {+        mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);+        return MV_BAD_PARAM;+    }+  +    vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));+    vlanPrioReg &= ~(0x7 << (vlanPrio*3));+    vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));+    MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);++    return MV_OK;+}+++/*******************************************************************************+* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.+*+* DESCRIPTION:+*       This function defines processing of BPDU packets. +*   BPDU packets can be accepted and captured to one of RX queues +*   or can be processing as regular Multicast packets. +*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*       int     bpduQueue   - Special queue to capture BPDU packets (DA is equal to +*                           01-80-C2-00-00-00 through 01-80-C2-00-00-FF, +*                           except for the Flow-Control Pause packets). +*                           Negative value (-1) means no special processing for BPDU, +*                           packets so they will be processed as regular Multicast packets.+*+* RETURN:   MV_STATUS+*       MV_OK       - Success+*       MV_FAIL     - Failed. +*+*******************************************************************************/+MV_STATUS   mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    MV_U32      portCfgReg;+    MV_U32      portCfgExtReg;++    if(bpduQueue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);+        return MV_BAD_PARAM;+    }+  +    portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));++    portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));+    if(bpduQueue >= 0)+    {+        pPortCtrl->portConfig.rxBpduQ = bpduQueue;++        portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;+        portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);++        MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);++        portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;+    }+    else+    {+        pPortCtrl->portConfig.rxBpduQ = -1;+        /* no special processing for BPDU packets */+        portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);+    }++    MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo),  portCfgExtReg);++    return MV_OK;+}+++/*******************************************************************************+* mvEthArpRxQueue - Configure RX queue to capture ARP packets.+*+* DESCRIPTION:+*       This function defines processing of ARP (type=0x0806) packets. +*   ARP packets can be accepted and captured to one of RX queues +*   or can be processed as other Broadcast packets. +*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*       int     arpQueue    - Special queue to capture ARP packets (type=0x806). +*                           Negative value (-1) means discard ARP packets+*+* RETURN:   MV_STATUS+*       MV_OK       - Success+*       MV_FAIL     - Failed. +*+*******************************************************************************/+MV_STATUS   mvEthArpRxQueue(void* pPortHandle, int arpQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    MV_U32      portCfgReg;++    if(arpQueue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);+        return MV_BAD_PARAM;+    }++    portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));++    if(arpQueue >= 0)+    {+        pPortCtrl->portConfig.rxArpQ = arpQueue;+        portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;+        portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);++        portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);+    }+    else+    {+        pPortCtrl->portConfig.rxArpQ = -1;+        portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;+    }++    MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);++    return MV_OK;+}+++/*******************************************************************************+* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.+*+* DESCRIPTION:+*       This function defines processing of TCP packets. +*   TCP packets can be accepted and captured to one of RX queues +*   or can be processed as regular Unicast packets. +*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*       int     tcpQueue    - Special queue to capture TCP packets. Value "-1" +*                           means no special processing for TCP packets, +*                           so they will be processed as regular+*+* RETURN:   MV_STATUS+*       MV_OK       - Success+*       MV_FAIL     - Failed. +*+*******************************************************************************/+MV_STATUS   mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    MV_U32      portCfgReg;++    if(tcpQueue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);+        return MV_BAD_PARAM;+    }+    portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));++    if(tcpQueue >= 0)+    {+        pPortCtrl->portConfig.rxTcpQ = tcpQueue;+        portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;+        portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);++        portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;+    }+    else+    {+        pPortCtrl->portConfig.rxTcpQ = -1;+        portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);+    }++    MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);++    return MV_OK;+}+++/*******************************************************************************+* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.+*+* DESCRIPTION:+*       This function defines processing of UDP packets. +*   TCP packets can be accepted and captured to one of RX queues +*   or can be processed as regular Unicast packets. +*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*       int     udpQueue    - Special queue to capture UDP packets. Value "-1" +*                           means no special processing for UDP packets, +*                           so they will be processed as regular+*+* RETURN:   MV_STATUS+*       MV_OK       - Success+*       MV_FAIL     - Failed. +*+*******************************************************************************/+MV_STATUS   mvEthUdpRxQueue(void* pPortHandle, int udpQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    MV_U32          portCfgReg;++    if(udpQueue >= MV_ETH_RX_Q_NUM)+    {+        mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);+        return MV_BAD_PARAM;+    }++    portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));++    if(udpQueue >= 0)+    {+        pPortCtrl->portConfig.rxUdpQ = udpQueue;+        portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;+        portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);++        portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;        +    }+    else+    {+        pPortCtrl->portConfig.rxUdpQ = -1;+        portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;+    }++    MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);++    return MV_OK;+}+++/******************************************************************************/+/*                          Speed, Duplex, FlowControl routines               */+/******************************************************************************/++/*******************************************************************************+* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.+*+* DESCRIPTION:+*       This function configure the port to work with desirable Duplex and Speed.+*       Changing of these parameters are allowed only when port is disabled.+*       This function disable the port if was enabled, change duplex and speed +*       and, enable the port back if needed.+*+* INPUT:+*       void*           pPortHandle - Pointer to port specific handler;+*       ETH_PORT_SPEED  speed       - Speed of the port.+*       ETH_PORT_SPEED  duplex      - Duplex of the port.+*+* RETURN:   MV_STATUS+*       MV_OK           - Success+*       MV_OUT_OF_RANGE - Failed. Port is out of valid range+*       MV_NOT_FOUND    - Failed. Port is not initialized.+*       MV_BAD_PARAM    - Input parameters (speed/duplex) in conflict.+*       MV_BAD_VALUE    - Value of one of input parameters (speed, duplex) +*                       is not valid+*+*******************************************************************************/+MV_STATUS   mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed, +                                MV_ETH_PORT_DUPLEX duplex)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;+    MV_U32      portSerialCtrlReg;+    +    if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )+        return MV_OUT_OF_RANGE;++    pPortCtrl = ethPortCtrl[port];+    if(pPortCtrl == NULL)+        return MV_NOT_FOUND;++    /* Check validity */+    if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )+        return MV_BAD_PARAM;++    portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));+    /* Set Speed */+    switch(speed)+    {+        case MV_ETH_SPEED_AN:+            portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;+            break;++        case MV_ETH_SPEED_10:+            portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;+            portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;+            portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;+            break;++        case MV_ETH_SPEED_100:+            portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;+            portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;+            portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;+            break;++        case MV_ETH_SPEED_1000:+            portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;+            portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;+            break;++        default:+            mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);+            return MV_BAD_VALUE;+    }+    /* Set duplex */+    switch(duplex)+    {+        case MV_ETH_DUPLEX_AN:+            portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;+            break;++        case MV_ETH_DUPLEX_HALF:+            portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;+            portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;+            break;++        case MV_ETH_DUPLEX_FULL:+            portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;+            portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;+            break;++        default:+            mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);+            return MV_BAD_VALUE;+    }+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);++    return MV_OK;+}++/*******************************************************************************+* mvEthFlowCtrlSet - Set Flow Control of the port.+*+* DESCRIPTION:+*       This function configure the port to work with desirable Duplex and +*       Speed. Changing of these parameters are allowed only when port is +*       disabled. This function disable the port if was enabled, change +*       duplex and speed and, enable the port back if needed.+*+* INPUT:+*       void*           pPortHandle - Pointer to port specific handler;+*       MV_ETH_PORT_FC  flowControl - Flow control of the port.+*+* RETURN:   MV_STATUS+*       MV_OK           - Success+*       MV_OUT_OF_RANGE - Failed. Port is out of valid range+*       MV_NOT_FOUND    - Failed. Port is not initialized.+*       MV_BAD_VALUE    - Value flowControl parameters is not valid+*+*******************************************************************************/+MV_STATUS   mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;+    MV_U32      portSerialCtrlReg;+    +    if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )+        return MV_OUT_OF_RANGE;++    pPortCtrl = ethPortCtrl[port];+    if(pPortCtrl == NULL)+        return MV_NOT_FOUND;++    portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));+    switch(flowControl)+    {+        case MV_ETH_FC_AN_ADV_DIS:+            portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;+            portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;+            break;++        case MV_ETH_FC_AN_ADV_SYM:+            portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;+            portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;+            break;++        case MV_ETH_FC_DISABLE:+            portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;+            portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;+            break;++        case MV_ETH_FC_ENABLE:+            portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;+            portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;+            break;++        default:+            mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);+            return MV_BAD_VALUE;+    }+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);++    return MV_OK;+}++/*******************************************************************************+* mvEthHeaderModeSet - Set port header mode.+*+* DESCRIPTION:+*       This function configures the port to work in Marvell-Header mode.+*+* INPUT:+*       void*           pPortHandle - Pointer to port specific handler;+*       MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.+*+* RETURN:   MV_STATUS+*       MV_OK           - Success+*       MV_NOT_SUPPORTED- Feature not supported.+*       MV_OUT_OF_RANGE - Failed. Port is out of valid range+*       MV_NOT_FOUND    - Failed. Port is not initialized.+*       MV_BAD_VALUE    - Value of headerMode or numRxQueue parameter is not valid.+*+*******************************************************************************/+MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;+    MV_U32			mvHeaderReg;+    MV_U32          numRxQ = MV_ETH_RX_Q_NUM;+    +    if((port < 0) || (port >= mvCtrlEthMaxPortGet()))+        return MV_OUT_OF_RANGE;++    pPortCtrl = ethPortCtrl[port];+    if(pPortCtrl == NULL)+        return MV_NOT_FOUND;++    mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));+    /* Disable header mode.             */+    mvHeaderReg &= ~ETH_MVHDR_EN_MASK;++    if(headerMode != MV_ETH_DISABLE_HEADER_MODE)+    {+        /* Enable Header mode.              */+        mvHeaderReg |= ETH_MVHDR_EN_MASK;++        /* Clear DA-Prefix  & MHMask fields.*/+        mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);++        if(numRxQ > 1)+        {+            switch (headerMode)+            {+                case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):+                    mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;+                    break;+                case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):+                    mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;+                    break;+                case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):+                    mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;+                    break;+                default:+                    break;+            }++            switch (numRxQ)+            {+                case (4):+                    mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;+                    break;+                case (8):+                    mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;+                    break;+                default:+                    break;+            }+        }+    }++    MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);++    return MV_OK;+}++#if (MV_ETH_VERSION >= 4)+/*******************************************************************************+* mvEthEjpModeSet - Enable / Disable EJP policy for TX.+*+* DESCRIPTION:+*       This function +*+* INPUT:+*       void*           pPortHandle - Pointer to port specific handler;+*       MV_BOOL         TRUE - enable EJP mode+*                       FALSE - disable EJP mode+*+* OUTPUT:   MV_STATUS+*       MV_OK           - Success+*       Other           - Failure+*+* RETURN:   None.+*+*******************************************************************************/+MV_STATUS    mvEthEjpModeSet(void* pPortHandle, int mode) +{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;+    +    if((port < 0) || (port >= mvCtrlEthMaxPortGet()))+        return MV_OUT_OF_RANGE;++    pPortCtrl = ethPortCtrl[port];+    if(pPortCtrl == NULL)+        return MV_NOT_FOUND;+    +    pPortCtrl->portConfig.ejpMode = mode;+    if(mode)+    {+        /* EJP enabled */+        MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);+    }+    else+    {+        /* EJP disabled */+        MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);+    }+    mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n", +        port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port), +                    MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));++    return MV_OK;+}+#endif /* MV_ETH_VERSION >= 4 */++/*******************************************************************************+* mvEthStatusGet - Get major properties of the port .+*+* DESCRIPTION:+*       This function get major properties of the port (link, speed, duplex, +*       flowControl, etc) and return them using the single structure.+*+* INPUT:+*       void*           pPortHandle - Pointer to port specific handler;+*+* OUTPUT:+*       MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status +*                                   will be placed.+*+* RETURN:   None.+*+*******************************************************************************/+void    mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;++    MV_U32  regValue;++    regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );++    if(regValue & ETH_GMII_SPEED_1000_MASK)+        pStatus->speed = MV_ETH_SPEED_1000;+    else if(regValue & ETH_MII_SPEED_100_MASK)+        pStatus->speed = MV_ETH_SPEED_100;+    else+        pStatus->speed = MV_ETH_SPEED_10;++    if(regValue & ETH_LINK_UP_MASK) +        pStatus->isLinkUp = MV_TRUE;+    else+        pStatus->isLinkUp = MV_FALSE;++    if(regValue & ETH_FULL_DUPLEX_MASK) +        pStatus->duplex = MV_ETH_DUPLEX_FULL; +    else+        pStatus->duplex = MV_ETH_DUPLEX_HALF; +++    if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) +        pStatus->flowControl = MV_ETH_FC_ENABLE;+    else+        pStatus->flowControl = MV_ETH_FC_DISABLE;+}+++/******************************************************************************/+/*                         PHY Control Functions                              */+/******************************************************************************/+++/*******************************************************************************+* mvEthPhyAddrSet - Set the ethernet port PHY address.+*+* DESCRIPTION:+*       This routine set the ethernet port PHY address according to given+*       parameter.+*+* INPUT:+*       void*   pPortHandle     - Pointer to port specific handler;+*       int     phyAddr         - PHY address       +*+* RETURN:+*       None.+*+*******************************************************************************/+void    mvEthPhyAddrSet(void* pPortHandle, int phyAddr)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;+    unsigned int    regData;++    regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));++    regData &= ~ETH_PHY_ADDR_MASK;+    regData |=  phyAddr;++    MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);++    return;+}++/*******************************************************************************+* mvEthPhyAddrGet - Get the ethernet port PHY address.+*+* DESCRIPTION:+*       This routine returns the given ethernet port PHY address.+*+* INPUT:+*       void*   pPortHandle - Pointer to port specific handler;+*+*+* RETURN: int - PHY address.+*+*******************************************************************************/+int     mvEthPhyAddrGet(void* pPortHandle)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;+    int             port = pPortCtrl->portNo;+    unsigned int    regData;++    regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));++    return ((regData >> (5 * port)) & 0x1f);+}++/******************************************************************************/+/*                Descriptor handling Functions                               */+/******************************************************************************/++/*******************************************************************************+* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.+*+* DESCRIPTION:+*       This function prepares a Rx chained list of descriptors and packet+*       buffers in a form of a ring. The routine must be called after port+*       initialization routine and before port start routine.+*       The Ethernet SDMA engine uses CPU bus addresses to access the various+*       devices in the system (i.e. DRAM). This function uses the ethernet+*       struct 'virtual to physical' routine (set by the user) to set the ring+*       with physical addresses.+*+* INPUT:+*       ETH_QUEUE_CTRL  *pEthPortCtrl   Ethernet Port Control srtuct.+*       int             rxQueue         Number of Rx queue.+*       int             rxDescNum       Number of Rx descriptors+*       MV_U8*          rxDescBaseAddr  Rx descriptors memory area base addr.+*+* OUTPUT:+*       The routine updates the Ethernet port control struct with information+*       regarding the Rx descriptors and buffers.+*+* RETURN: None+*+*******************************************************************************/+static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)+{+    ETH_RX_DESC     *pRxDescBase, *pRxDesc, *pRxPrevDesc; +    int             ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;+    ETH_QUEUE_CTRL  *pQueueCtrl = &pPortCtrl->rxQueue[queue];++    /* Make sure descriptor address is cache line size aligned  */        +    pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,+                                     CPU_D_CACHE_LINE_SIZE);++    pRxDesc      = (ETH_RX_DESC*)pRxDescBase;+    pRxPrevDesc  = pRxDesc;++    /* initialize the Rx descriptors ring */+    for (ix=0; ix<rxDescNum; ix++)+    {+        pRxDesc->bufSize     = 0x0;+        pRxDesc->byteCnt     = 0x0;+        pRxDesc->cmdSts      = ETH_BUFFER_OWNED_BY_HOST;+        pRxDesc->bufPtr      = 0x0;+        pRxDesc->returnInfo  = 0x0;+        pRxPrevDesc = pRxDesc;+        if(ix == (rxDescNum-1))+        {+            /* Closing Rx descriptors ring */+            pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);+        }+        else+        {+            pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);+            pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);+        }+        ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);+    }++    pQueueCtrl->pCurrentDescr = pRxDescBase;+    pQueueCtrl->pUsedDescr = pRxDescBase;+    +    pQueueCtrl->pFirstDescr = pRxDescBase;+    pQueueCtrl->pLastDescr = pRxDesc;+    pQueueCtrl->resource = 0;+}++void ethResetRxDescRing(void* pPortHndl, int queue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];+    ETH_RX_DESC*    pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;++    pQueueCtrl->resource = 0;+    if(pQueueCtrl->pFirstDescr != NULL)+    {+        while(MV_TRUE)+        {+            pRxDesc->bufSize     = 0x0;+            pRxDesc->byteCnt     = 0x0;+            pRxDesc->cmdSts      = ETH_BUFFER_OWNED_BY_HOST;+            pRxDesc->bufPtr      = 0x0;+            pRxDesc->returnInfo  = 0x0;+            ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);+            if( (void*)pRxDesc == pQueueCtrl->pLastDescr)+                    break;+            pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);+        }+        pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;+        pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;++        /* Update RX Command register */+        pPortCtrl->portRxQueueCmdReg |= (1 << queue);++        /* update HW */+        MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),+                 (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );+    }+    else+    {+        /* Update RX Command register */+        pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);++        /* update HW */+        MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);+    }+}++/*******************************************************************************+* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.+*+* DESCRIPTION:+*       This function prepares a Tx chained list of descriptors and packet+*       buffers in a form of a ring. The routine must be called after port+*       initialization routine and before port start routine.+*       The Ethernet SDMA engine uses CPU bus addresses to access the various+*       devices in the system (i.e. DRAM). This function uses the ethernet+*       struct 'virtual to physical' routine (set by the user) to set the ring+*       with physical addresses.+*+* INPUT:+*       ETH_PORT_CTRL   *pEthPortCtrl   Ethernet Port Control srtuct.+*       int             txQueue         Number of Tx queue.+*       int             txDescNum       Number of Tx descriptors+*       int             txBuffSize      Size of Tx buffer+*       MV_U8*          pTxDescBase     Tx descriptors memory area base addr.+*+* OUTPUT:+*       The routine updates the Ethernet port control struct with information+*       regarding the Tx descriptors and buffers.+*+* RETURN:   None.+*+*******************************************************************************/+static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)+{+    ETH_TX_DESC     *pTxDescBase, *pTxDesc, *pTxPrevDesc; +    int             ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;+    ETH_QUEUE_CTRL  *pQueueCtrl = &pPortCtrl->txQueue[queue];++    /* Make sure descriptor address is cache line size aligned  */+    pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr, +                                     CPU_D_CACHE_LINE_SIZE);++    pTxDesc      = (ETH_TX_DESC*)pTxDescBase;+    pTxPrevDesc  = pTxDesc;++    /* initialize the Tx descriptors ring */+    for (ix=0; ix<txDescNum; ix++)+    {+        pTxDesc->byteCnt     = 0x0000;+        pTxDesc->L4iChk      = 0x0000;+        pTxDesc->cmdSts      = ETH_BUFFER_OWNED_BY_HOST;+        pTxDesc->bufPtr      = 0x0;+        pTxDesc->returnInfo  = 0x0;++        pTxPrevDesc = pTxDesc;++        if(ix == (txDescNum-1))+        {+            /* Closing Tx descriptors ring */+            pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);+        }+        else+        {+            pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);+            pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);+        }+        ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);+    }++    pQueueCtrl->pCurrentDescr = pTxDescBase;+    pQueueCtrl->pUsedDescr = pTxDescBase;+    +    pQueueCtrl->pFirstDescr = pTxDescBase;+    pQueueCtrl->pLastDescr = pTxDesc;+    /* Leave one TX descriptor out of use */+    pQueueCtrl->resource = txDescNum - 1;+}++void ethResetTxDescRing(void* pPortHndl, int queue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];+    ETH_TX_DESC*    pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;+    +    pQueueCtrl->resource = 0;+    if(pQueueCtrl->pFirstDescr != NULL)+    {+        while(MV_TRUE)+        {+            pTxDesc->byteCnt     = 0x0000;+            pTxDesc->L4iChk      = 0x0000;+            pTxDesc->cmdSts      = ETH_BUFFER_OWNED_BY_HOST;+            pTxDesc->bufPtr      = 0x0;+            pTxDesc->returnInfo  = 0x0;+            ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);+            pQueueCtrl->resource++;+            if( (void*)pTxDesc == pQueueCtrl->pLastDescr)+                    break;+            pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);+        }+        /* Leave one TX descriptor out of use */+        pQueueCtrl->resource--;+        pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;+        pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;++        /* Update TX Command register */+        pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);+        /* update HW */+        MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),+        (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );+    }+    else+    {+        /* Update TX Command register */+        pPortCtrl->portTxQueueCmdReg &=  MV_32BIT_LE_FAST(~(1 << queue));+        /* update HW */+        MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );    +    }+}++/*******************************************************************************+* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.+*+* DESCRIPTION:+*       This function allocates memory for RX and TX descriptors.+*       - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.+*       - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.+*+* INPUT:+*       int size - size of memory should be allocated.+*+* RETURN: None+*+*******************************************************************************/+static MV_U8*  ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize, +                            MV_ULONG* pPhysAddr, MV_U32 *memHandle)+{+    MV_U8*  pVirt;++#if defined(ETH_DESCR_IN_SRAM)+    if(ethDescInSram == MV_TRUE)+        pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);+    else+#endif /* ETH_DESCR_IN_SRAM */+    {+#ifdef ETH_DESCR_UNCACHED+        pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,+					    pPhysAddr,memHandle);+#else+        pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,+					  pPhysAddr, memHandle);+#endif /* ETH_DESCR_UNCACHED */+    }+    memset(pVirt, 0, descSize);++    return pVirt;+}++/*******************************************************************************+* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.+*+* DESCRIPTION:+*       This function frees memory allocated for RX and TX descriptors.+*       - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.+*       - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.+*+* INPUT:+*       void* pVirtAddr - virtual pointer to memory allocated for RX and TX+*                       desriptors.        +*+* RETURN: None+*+*******************************************************************************/+void    ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)+{+    if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )+        return;++#if defined(ETH_DESCR_IN_SRAM)+    if( ethDescInSram )+    {+        mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);+        return;+    }+#endif /* ETH_DESCR_IN_SRAM */++#ifdef ETH_DESCR_UNCACHED+    mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr, +                     pDescBuf->bufVirtPtr,pDescBuf->memHandle);+#else+    mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr, +                     pDescBuf->bufVirtPtr,pDescBuf->memHandle);+#endif /* ETH_DESCR_UNCACHED */+}+                                                                                                                             +/******************************************************************************/+/*                Other Functions                                         */+/******************************************************************************/++void mvEthPortPowerUp(int port)+{+    MV_U32  regVal;++    /* MAC Cause register should be cleared */+    MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);++	if (mvBoardIsPortInSgmii(port))+    mvEthPortSgmiiConfig(port);++    /* Cancel Port Reset */+    regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));+    regVal &= (~ETH_PORT_RESET_MASK);+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);+    while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);+}++void mvEthPortPowerDown(int port)+{+    MV_U32  regVal;++    /* Port must be DISABLED */+    regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));+    if( (regVal & ETH_PORT_ENABLE_MASK) != 0)+    {+        mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",+                    port, regVal);+        return;+    }++    /* Port Reset (Read after write the register as a precaution) */+    regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));+    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);+    while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);+}++static void mvEthPortSgmiiConfig(int port)+{+    MV_U32  regVal;++    regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));++    regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);+    regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);++    MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);+}+++++++++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c	2010-11-09 20:28:11.072495491 +0100@@ -0,0 +1,748 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/*******************************************************************************+* mvEthDebug.c - Source file for user friendly debug functions+*+* DESCRIPTION:+*+* DEPENDENCIES:+*       None.+*+*******************************************************************************/++#include "mvOs.h"+#include "mvCommon.h"+#include "mvTypes.h"+#include "mv802_3.h"+#include "mvDebug.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "eth-phy/mvEthPhy.h"+#include "eth/mvEth.h"+#include "eth/gbe/mvEthDebug.h"++/* #define mvOsPrintf printf */++void    mvEthPortShow(void* pHndl);+void    mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);++/******************************************************************************/+/*                          Debug functions                                   */+/******************************************************************************/+void    ethRxCoal(int port, int usec)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthRxCoalSet(pHndl, usec);+    }+}++void    ethTxCoal(int port, int usec)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthTxCoalSet(pHndl, usec);+    }+}++#if (MV_ETH_VERSION >= 4)+void     ethEjpModeSet(int port, int mode)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthEjpModeSet(pHndl, mode);+    }+}+#endif /* (MV_ETH_VERSION >= 4) */++void    ethBpduRxQ(int port, int bpduQueue)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthBpduRxQueue(pHndl, bpduQueue);+    }+}++void    ethArpRxQ(int port, int arpQueue)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthArpRxQueue(pHndl, arpQueue);+    }+}++void    ethTcpRxQ(int port, int tcpQueue)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthTcpRxQueue(pHndl, tcpQueue);+    }+}++void    ethUdpRxQ(int port, int udpQueue)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthUdpRxQueue(pHndl, udpQueue);+    }+}++void    ethTxPolicyRegs(int port)+{+    int             queue;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);++    if(pPortCtrl == NULL) +    {+        return;+    }+    mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ", +                port, pPortCtrl->portConfig.ejpMode);+    for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)+    {+        if(pPortCtrl->txQueueConfig[queue].descrNum > 0)+            mvOsPrintf("%d, ", queue);+    }+    mvOsPrintf("\n");++    mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);++    mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG            : 0x%X = 0x%08x\n", +                ETH_TX_QUEUE_COMMAND_REG(port), +                MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );    +    +    mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG           : 0x%X = 0x%08x\n", +                ETH_TX_FIXED_PRIO_CFG_REG(port), +                MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );++    mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG           : 0x%X = 0x%08x\n", +                ETH_TX_TOKEN_RATE_CFG_REG(port), +                MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );++    mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG           : 0x%X = 0x%08x\n", +                ETH_MAX_TRANSMIT_UNIT_REG(port), +                MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );++    mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG        : 0x%X = 0x%08x\n", +                ETH_TX_TOKEN_BUCKET_SIZE_REG(port), +                MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );++    mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG       : 0x%X = 0x%08x\n", +                ETH_TX_TOKEN_BUCKET_COUNT_REG(port), +                MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );++    for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)+    {+        mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);++        mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG             : 0x%X = 0x%08x\n", +                ETH_TXQ_TOKEN_COUNT_REG(port, queue), +                MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );++        mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG               : 0x%X = 0x%08x\n", +                ETH_TXQ_TOKEN_CFG_REG(port, queue), +                MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );++        mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG             : 0x%X = 0x%08x\n", +                ETH_TXQ_ARBITER_CFG_REG(port, queue), +                MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );+    }+    mvOsPrintf("\n");+}++/* Print important registers of Ethernet port */+void    ethPortRegs(int port)+{+    mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);++    mvOsPrintf("ETH_PORT_STATUS_REG                 : 0x%X = 0x%08x\n", +                ETH_PORT_STATUS_REG(port), +                MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );++    mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG            : 0x%X = 0x%08x\n", +                ETH_PORT_SERIAL_CTRL_REG(port), +                MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );++    mvOsPrintf("ETH_PORT_CONFIG_REG                 : 0x%X = 0x%08x\n", +                ETH_PORT_CONFIG_REG(port), +                MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );    ++    mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG          : 0x%X = 0x%08x\n", +                ETH_PORT_CONFIG_EXTEND_REG(port), +                MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );    ++    mvOsPrintf("ETH_SDMA_CONFIG_REG                 : 0x%X = 0x%08x\n", +                ETH_SDMA_CONFIG_REG(port), +                MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );    ++    mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG       : 0x%X = 0x%08x\n", +                ETH_TX_FIFO_URGENT_THRESH_REG(port), +                MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );    ++    mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG            : 0x%X = 0x%08x\n", +                ETH_RX_QUEUE_COMMAND_REG(port), +                MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );    ++    mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG            : 0x%X = 0x%08x\n", +                ETH_TX_QUEUE_COMMAND_REG(port), +                MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );    ++    mvOsPrintf("ETH_INTR_CAUSE_REG                  : 0x%X = 0x%08x\n", +                ETH_INTR_CAUSE_REG(port), +                MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );    ++    mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG           : 0x%X = 0x%08x\n", +                ETH_INTR_CAUSE_EXT_REG(port), +                MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );    ++    mvOsPrintf("ETH_INTR_MASK_REG                   : 0x%X = 0x%08x\n", +                ETH_INTR_MASK_REG(port), +                MV_REG_READ( ETH_INTR_MASK_REG(port) ) );    ++    mvOsPrintf("ETH_INTR_EXTEND_MASK_REG            : 0x%X = 0x%08x\n", +                ETH_INTR_MASK_EXT_REG(port), +                MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );    ++    mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG           : 0x%X = 0x%08x\n", +                ETH_RX_DESCR_STAT_CMD_REG(port, 0), +                MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );    ++    mvOsPrintf("ETH_RX_BYTE_COUNT_REG               : 0x%X = 0x%08x\n", +                ETH_RX_BYTE_COUNT_REG(port, 0), +                MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );    ++    mvOsPrintf("ETH_RX_BUF_PTR_REG                  : 0x%X = 0x%08x\n", +                ETH_RX_BUF_PTR_REG(port, 0), +                MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );    ++    mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG             : 0x%X = 0x%08x\n", +                ETH_RX_CUR_DESC_PTR_REG(port, 0), +                MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );    +}+++/* Print Giga Ethernet UNIT registers */+void    ethRegs(int port)+{+    mvOsPrintf("ETH_PHY_ADDR_REG               : 0x%X = 0x%08x\n", +                ETH_PHY_ADDR_REG(port), +                MV_REG_READ(ETH_PHY_ADDR_REG(port)) );    ++    mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG        : 0x%X = 0x%08x\n", +                ETH_UNIT_INTR_CAUSE_REG(port), +                MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );    ++    mvOsPrintf("ETH_UNIT_INTR_MASK_REG         : 0x%X = 0x%08x\n", +                ETH_UNIT_INTR_MASK_REG(port), +                MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );    ++    mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG        : 0x%X = 0x%08x\n", +                ETH_UNIT_ERROR_ADDR_REG(port), +                MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );    ++    mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG    : 0x%X = 0x%08x\n", +                ETH_UNIT_INT_ADDR_ERROR_REG(port), +                MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );    +    +}++/******************************************************************************/+/*                      MIB Counters functions                                */+/******************************************************************************/++/*******************************************************************************+* ethClearMibCounters - Clear all MIB counters+*+* DESCRIPTION:+*       This function clears all MIB counters of a specific ethernet port.+*       A read from the MIB counter will reset the counter.+*+* INPUT:+*       int    port -  Ethernet Port number.+*+* RETURN: None+*+*******************************************************************************/+void ethClearCounters(int port)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+        mvEthMibCountersClear(pHndl);++    return;+}+++/* Print counters of the Ethernet port */+void    ethPortCounters(int port)+{+    MV_U32  regValue, regValHigh;+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl == NULL)+        return;++    mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);++    mvOsPrintf("GoodFramesReceived          = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));+    mvOsPrintf("BadFramesReceived           = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));+    mvOsPrintf("BroadcastFramesReceived     = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));+    mvOsPrintf("MulticastFramesReceived     = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, +                                 ®ValHigh);+    mvOsPrintf("GoodOctetsReceived          = 0x%08x%08x\n", +               regValHigh, regValue);++    mvOsPrintf("\n");+    mvOsPrintf("GoodFramesSent              = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));+    mvOsPrintf("BroadcastFramesSent         = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));+    mvOsPrintf("MulticastFramesSent         = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW, +                                 ®ValHigh);+    mvOsPrintf("GoodOctetsSent              = 0x%08x%08x\n", regValHigh, regValue);+++    mvOsPrintf("\n\t FC Control Counters\n");++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);+    mvOsPrintf("UnrecogMacControlReceived   = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);+    mvOsPrintf("GoodFCFramesReceived        = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);+    mvOsPrintf("BadFCFramesReceived         = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);+    mvOsPrintf("FCFramesSent                = %u\n", regValue);+++    mvOsPrintf("\n\t RX Errors\n");++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);+    mvOsPrintf("BadOctetsReceived           = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);+    mvOsPrintf("UndersizeFramesReceived     = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);+    mvOsPrintf("FragmentsReceived           = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);+    mvOsPrintf("OversizeFramesReceived      = %u\n", regValue);+    +    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);+    mvOsPrintf("JabbersReceived             = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);+    mvOsPrintf("MacReceiveErrors            = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);+    mvOsPrintf("BadCrcReceived              = %u\n", regValue);++    mvOsPrintf("\n\t TX Errors\n");++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);+    mvOsPrintf("TxMacErrors                 = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);+    mvOsPrintf("TxExcessiveCollisions       = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);+    mvOsPrintf("TxCollisions                = %u\n", regValue);++    regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);+    mvOsPrintf("TxLateCollisions            = %u\n", regValue);+++    mvOsPrintf("\n");+    regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));+    mvOsPrintf("Rx Discard packets counter  = %u\n", regValue);++    regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));+    mvOsPrintf("Rx Overrun packets counter  = %u\n", regValue);+}++/* Print RMON counters of the Ethernet port */+void    ethPortRmonCounters(int port)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl == NULL)+        return;++    mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);++    mvOsPrintf("64 ByteFramesReceived           = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));+    mvOsPrintf("65...127 ByteFramesReceived     = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));+    mvOsPrintf("128...255 ByteFramesReceived    = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));+    mvOsPrintf("256...511 ByteFramesReceived    = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));+    mvOsPrintf("512...1023 ByteFramesReceived   = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));+    mvOsPrintf("1024...Max ByteFramesReceived   = %u\n", +              mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));+}++/* Print port information */+void    ethPortStatus(int port)+{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthPortShow(pHndl);+    }+}++/* Print port queues information */+void    ethPortQueues(int port, int rxQueue, int txQueue, int mode)  +{+    void*   pHndl;++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);+    }+}++void    ethUcastSet(int port, char* macStr, int queue)+{+    void*   pHndl;+    MV_U8   macAddr[MV_MAC_ADDR_SIZE];++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvMacStrToHex(macStr, macAddr);+        mvEthMacAddrSet(pHndl, macAddr, queue);+    }+}+++void    ethPortUcastShow(int port)+{+    MV_U32  unicastReg, macL, macH;+    int     i, j;++    macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));+    macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));+ +    mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n", +                port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),+                      ((macH >> 8) & 0xff), (macH  & 0xff), +                      ((macL >> 8) & 0xff), (macL  & 0xff) );++    for (i=0; i<4; i++)+    {+        unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));+        for(j=0; j<4; j++)+        {+            MV_U8   macEntry = (unicastReg >> (8*j)) & 0xFF;++            mvOsPrintf("%X: %8s, Q = %d\n", i*4+j, +                (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);+        }+    }+} ++void    ethMcastAdd(int port, char* macStr, int queue)+{+    void*   pHndl;+    MV_U8   macAddr[MV_MAC_ADDR_SIZE];++    pHndl = mvEthPortHndlGet(port);+    if(pHndl != NULL)+    {+        mvMacStrToHex(macStr, macAddr);+        mvEthMcastAddrSet(pHndl, macAddr, queue);+    }+}++void    ethPortMcast(int port)+{+    int     tblIdx, regIdx;+    MV_U32  regVal;++    mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n", +                port);++    for(tblIdx=0; tblIdx<(256/4); tblIdx++)+    {+        regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));+        for(regIdx=0; regIdx<4; regIdx++)+        {+            if((regVal & (0x01 << (regIdx*8))) != 0)+            {+                mvOsPrintf("0x%02X: Accepted, rxQ = %d\n", +                    tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));+            }+        }+    }+    mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);+    for(tblIdx=0; tblIdx<(256/4); tblIdx++)+    {+        regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));+        for(regIdx=0; regIdx<4; regIdx++)+        {+            if((regVal & (0x01 << (regIdx*8))) != 0)+            {+                mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n", +                    tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));+            }+        }+    }+}+++/* Print status of Ethernet port */+void    mvEthPortShow(void* pHndl)+{+    MV_U32              regValue, rxCoal, txCoal;+    int                 speed, queue, port;+    ETH_PORT_CTRL*      pPortCtrl = (ETH_PORT_CTRL*)pHndl;++    port = pPortCtrl->portNo;++    regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );++    mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n", +                port, ETH_PORT_STATUS_REG(port), regValue);++    mvOsPrintf("descInSram=%d, descSwCoher=%d\n", +                ethDescInSram, ethDescSwCoher);++    if(regValue & ETH_GMII_SPEED_1000_MASK)+        speed = 1000;+    else if(regValue & ETH_MII_SPEED_100_MASK)+        speed = 100;+    else+        speed = 10;++    mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);++    /* Link, Speed, Duplex, FlowControl */+    mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",+                (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",+                speed, +                (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",+                (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");++    mvOsPrintf("\n");++    mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n", +                rxCoal, txCoal);++    mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",+                pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ, +                pPortCtrl->portConfig.rxBpduQ, +                pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ); ++    /* Print all RX and TX queues */+    for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)+    {+        mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n", +                    queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,+                    mvEthRxResourceGet(pPortCtrl, queue) );+    }+    mvOsPrintf("\n");+    for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)+    {+        mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n", +                queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,+                mvEthTxResourceGet(pPortCtrl, queue) );+    }+}++/* Print RX and TX queue of the Ethernet port */+void    mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)  +{+    ETH_PORT_CTRL   *pPortCtrl = (ETH_PORT_CTRL*)pHndl;+    ETH_QUEUE_CTRL  *pQueueCtrl;+    MV_U32          regValue;+    ETH_RX_DESC     *pRxDescr;+    ETH_TX_DESC     *pTxDescr;+    int             i, port = pPortCtrl->portNo;++    if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )+    {+        pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);+        mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);++        mvOsPrintf("CURR_RX_DESC_PTR        : 0x%X = 0x%08x\n", +            ETH_RX_CUR_DESC_PTR_REG(port, rxQueue), +            MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));+++        if(pQueueCtrl->pFirstDescr != NULL)+        {+            mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",+                (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr, +                pQueueCtrl->resource);+            mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",+                (MV_ULONG)pQueueCtrl->pCurrentDescr, +                (MV_ULONG)pQueueCtrl->pUsedDescr);++            if(mode == 1)+            {+                pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;+                i = 0; +                do +                {+                    mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n", +                                i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr), +                                pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize, +                                (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,+                                ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);++                    ETH_DESCR_INV(pPortCtrl, pRxDescr);+                    pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);+                    i++;+                } while (pRxDescr != pQueueCtrl->pFirstDescr);+            }+        }+        else+            mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);+    }++    if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )+    {+        pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);+        mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);++        regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));+        mvOsPrintf("CURR_TX_DESC_PTR        : 0x%X = 0x%08x\n", +                    ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);++        if(pQueueCtrl->pFirstDescr != NULL)+        {+            mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",+                       (MV_ULONG)pQueueCtrl->pFirstDescr, +                       (MV_ULONG)pQueueCtrl->pLastDescr, +                        pQueueCtrl->resource);+            mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",+                       (MV_ULONG)pQueueCtrl->pCurrentDescr, +                       (MV_ULONG)pQueueCtrl->pUsedDescr);++            if(mode == 1)+            {+                pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;+                i = 0; +                do +                {+                    mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n", +                                i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr), +                                pTxDescr->cmdSts, pTxDescr->byteCnt, +                                (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,+                                pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);++                    ETH_DESCR_INV(pPortCtrl, pTxDescr);+                    pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);+                    i++;+                } while (pTxDescr != pQueueCtrl->pFirstDescr);+            }+        }+        else+            mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);+    }+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h	2010-11-09 20:28:11.112495471 +0100@@ -0,0 +1,146 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#ifndef __MV_ETH_DEBUG_H__+#define __MV_ETH_DEBUG_H__++#if 0+/*+ ** Externs+ */+void     ethBpduRxQ(int port, int bpduQueue);+void     ethArpRxQ(int port, int bpduQueue);+void     ethTcpRxQ(int port, int bpduQueue);+void     ethUdpRxQ(int port, int bpduQueue);+void     ethMcastAdd(int port, char* macStr, int queue);++#ifdef INCLUDE_MULTI_QUEUE+void   	ethRxPolicy( int port);+void   	ethTxPolicy( int port);+void   	ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);+void   	ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);+void    ethRxPolQ(int port, int rxQueue, int rxQuota);+#endif /* INCLUDE_MULTI_QUEUE */++void    print_egiga_stat(void *sc, unsigned int port);+void    ethPortStatus (int port);+void    ethPortQueues( int port, int rxQueue, int txQueue, int mode);+void    ethPortMcast(int port);+void    ethPortRegs(int port);+void    ethPortCounters(int port);+void 	ethPortRmonCounters(int port);+void    ethRxCoal(int port, int usec);+void    ethTxCoal(int port, int usec);++void    ethRegs(int port);+void	ethClearCounters(int port);+void    ethUcastSet(int port, char* macStr, int queue);+void    ethPortUcastShow(int port);++#ifdef CONFIG_MV_ETH_HEADER+void	run_com_header(const char *buffer);+#endif++#ifdef INCLUDE_MULTI_QUEUE+void    ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);+void    ethRxPolQ(int port, int queue, int quota);+void    ethRxPolicy(int port);+void    ethTxPolDef(int port, int txQ, char* headerHexStr);+void    ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);+void    ethTxPolicy(int port);+#endif /* INCLUDE_MULTI_QUEUE */++#if (MV_ETH_VERSION >= 4)+void     ethEjpModeSet(int port, int mode)+#endif+#endif /* 0 */+++++void    ethRxCoal(int port, int usec);+void    ethTxCoal(int port, int usec);+#if (MV_ETH_VERSION >= 4)+void     ethEjpModeSet(int port, int mode);+#endif /* (MV_ETH_VERSION >= 4) */++void    ethBpduRxQ(int port, int bpduQueue);+void    ethArpRxQ(int port, int arpQueue);+void    ethTcpRxQ(int port, int tcpQueue);+void    ethUdpRxQ(int port, int udpQueue);+void    ethTxPolicyRegs(int port);+void    ethPortRegs(int port);+void    ethRegs(int port);+void ethClearCounters(int port);+void    ethPortCounters(int port);+void    ethPortRmonCounters(int port);+void    ethPortStatus(int port);+void    ethPortQueues(int port, int rxQueue, int txQueue, int mode);+void    ethUcastSet(int port, char* macStr, int queue);+void    ethPortUcastShow(int port);+void    ethMcastAdd(int port, char* macStr, int queue);+void    ethPortMcast(int port);+void    mvEthPortShow(void* pHndl);+void    mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);++#endifdiff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h	2010-11-09 20:28:11.152495442 +0100@@ -0,0 +1,751 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/*******************************************************************************+* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller+*+* DESCRIPTION:+*       This header file contains macros typedefs and function declaration specific to +*       the Marvell Gigabit Ethernet Controller.+*+* DEPENDENCIES:+*       None.+*+*******************************************************************************/++#ifndef __mvEthGbe_h__+#define __mvEthGbe_h__++extern MV_BOOL         ethDescInSram;+extern MV_BOOL         ethDescSwCoher;+extern ETH_PORT_CTRL*  ethPortCtrl[];++static INLINE MV_ULONG  ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)+{+#if defined (ETH_DESCR_IN_SRAM)+    if( ethDescInSram )+        return mvSramVirtToPhy(pDesc);+    else+#endif /* ETH_DESCR_IN_SRAM */+        return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));+}+/* Return port handler */+#define mvEthPortHndlGet(port)  ethPortCtrl[port]++/* Used as WA for HW/SW race on TX */+static INLINE int      mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)+{+    int                 deep = 0;+    MV_U32              txCurrReg, txEnReg;+    ETH_TX_DESC*        pTxLastDesc;+    ETH_QUEUE_CTRL*     pQueueCtrl;+    ETH_PORT_CTRL*      pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));+    if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)+    {+        MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;+        return 0;+    }++    pQueueCtrl = &pPortCtrl->txQueue[queue];+    pTxLastDesc = pQueueCtrl->pCurrentDescr;+    txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));+    if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)+    {+        /* All descriptors are processed, no chance for race */+        return 0;+    }++    /* Check distance betwee HW and SW location: */+    /* If distance between HW and SW pointers is less than max_deep descriptors */+    /* Race condition is possible, so wait end of TX and restart TXQ */+    while(deep < max_deep)+    {+        pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);+        if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)+        {+            int count = 0;++            while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)+            {   +                count++;+                if(count > 10000)+                {+                    mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n", +                                MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );+                    break;+                }+                txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));+            }++            MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;+            return count;+        }+        deep++;+    }+    /* Distance between HW and SW pointers is more than max_deep descriptors, */+    /* So NO race condition - do nothing */+    return -1;+}+++/* defines  */+#define ETH_CSUM_MIN_BYTE_COUNT     72++/* Tailgate and Kirwood have only 2K TX FIFO */+#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)+#define ETH_CSUM_MAX_BYTE_COUNT     1600+#else+#define ETH_CSUM_MAX_BYTE_COUNT     9*1024+#endif /* MV_ETH_VERSION */++#define ETH_MV_HEADER_SIZE	    2+#define ETH_MV_TX_EN++/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */+#define MIN_TX_BUFF_LOAD            8+#define TX_BUF_OFFSET_IN_DESC       (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)++/* Default port configuration value */+#define PORT_CONFIG_VALUE                       \+             ETH_DEF_RX_QUEUE_MASK(0)       |   \+             ETH_DEF_RX_ARP_QUEUE_MASK(0)   |   \+             ETH_DEF_RX_TCP_QUEUE_MASK(0)   |   \+             ETH_DEF_RX_UDP_QUEUE_MASK(0)   |   \+             ETH_DEF_RX_BPDU_QUEUE_MASK(0)  |   \+             ETH_RX_CHECKSUM_WITH_PSEUDO_HDR++/* Default port extend configuration value */+#define PORT_CONFIG_EXTEND_VALUE            0++#define PORT_SERIAL_CONTROL_VALUE                           \+            ETH_DISABLE_FC_AUTO_NEG_MASK                |   \+            BIT9                                        |   \+            ETH_DO_NOT_FORCE_LINK_FAIL_MASK             |   \+            ETH_MAX_RX_PACKET_1552BYTE                  |   \+            ETH_SET_FULL_DUPLEX_MASK++#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE               \+            ETH_FORCE_LINK_PASS_MASK                    |   \+            ETH_DISABLE_DUPLEX_AUTO_NEG_MASK            |   \+            ETH_DISABLE_FC_AUTO_NEG_MASK                |   \+            BIT9                                        |   \+            ETH_DO_NOT_FORCE_LINK_FAIL_MASK             |   \+            ETH_DISABLE_SPEED_AUTO_NEG_MASK             |   \+            ETH_SET_FULL_DUPLEX_MASK                    |   \+            ETH_SET_MII_SPEED_100_MASK                  |   \+            ETH_MAX_RX_PACKET_1552BYTE+++#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE              \+            ETH_FORCE_LINK_PASS_MASK                    |   \+            ETH_DISABLE_DUPLEX_AUTO_NEG_MASK            |   \+            ETH_DISABLE_FC_AUTO_NEG_MASK                |   \+            BIT9                                        |   \+            ETH_DO_NOT_FORCE_LINK_FAIL_MASK             |   \+            ETH_DISABLE_SPEED_AUTO_NEG_MASK             |   \+            ETH_SET_FULL_DUPLEX_MASK                    |   \+            ETH_SET_GMII_SPEED_1000_MASK                |   \+            ETH_MAX_RX_PACKET_1552BYTE++#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE                \+            ETH_DISABLE_FC_AUTO_NEG_MASK                |   \+            BIT9                                        |   \+            ETH_IN_BAND_AN_EN_MASK                      |   \+            ETH_DO_NOT_FORCE_LINK_FAIL_MASK             |   \+            ETH_MAX_RX_PACKET_1552BYTE                  ++/* Function headers: */+MV_VOID     mvEthSetSpecialMcastTable(int portNo, int queue);+MV_STATUS   mvEthArpRxQueue(void* pPortHandle, int arpQueue);+MV_STATUS   mvEthUdpRxQueue(void* pPortHandle, int udpQueue);+MV_STATUS   mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);+MV_STATUS   mvEthMacAddrGet(int portNo, unsigned char *pAddr);+MV_VOID     mvEthSetOtherMcastTable(int portNo, int queue);+MV_STATUS   mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);+/* Interrupt Coalesting functions */+MV_U32      mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);+MV_U32      mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);+MV_STATUS   mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);++/******************************************************************************/+/*                          Data Flow functions                               */+/******************************************************************************/+static INLINE void      mvEthPortTxRestart(void* pPortHndl)+{+    ETH_PORT_CTRL*      pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;+}++/* Get number of Free resources in specific TX queue */+static INLINE int     mvEthTxResourceGet(void* pPortHndl, int txQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    return (pPortCtrl->txQueue[txQueue].resource);      +}++/* Get number of Free resources in specific RX queue */+static INLINE int     mvEthRxResourceGet(void* pPortHndl, int rxQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    return (pPortCtrl->rxQueue[rxQueue].resource);      +}++static INLINE int     mvEthTxQueueIsFull(void* pPortHndl, int txQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    if(pPortCtrl->txQueue[txQueue].resource == 0)+        return MV_TRUE;++    return MV_FALSE;+}++/* Get number of Free resources in specific RX queue */+static INLINE int     mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];++    if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) && +        (pQueueCtrl->resource != 0) )+        return MV_TRUE;++    return MV_FALSE;+}++static INLINE int     mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];++    if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&+        (pQueueCtrl->resource != 0) )+    {+        return MV_TRUE;+    }+    return MV_FALSE;+}++/* Get number of Free resources in specific RX queue */+static INLINE int     mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)+{+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;++    if(pPortCtrl->rxQueue[rxQueue].resource == 0)+        return MV_TRUE;++    return MV_FALSE;+}++/*******************************************************************************+* mvEthPortTx - Send an Ethernet packet+*+* DESCRIPTION:+*       This routine send a given packet described by pPktInfo parameter. +*       Single buffer only.+*+* INPUT:+*       void*       pEthPortHndl  - Ethernet Port handler.+*       int         txQueue       - Number of Tx queue.+*       MV_PKT_INFO *pPktInfo     - User packet to send.+*+* RETURN:+*       MV_NO_RESOURCE  - No enough resources to send this packet.+*       MV_ERROR        - Unexpected Fatal error.+*       MV_OK           - Packet send successfully.+*+*******************************************************************************/+static INLINE MV_STATUS   mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)+{+    ETH_TX_DESC*    pTxCurrDesc;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl;+    int             portNo;+    MV_BUF_INFO*    pBufInfo = pPktInfo->pFrags;++#ifdef ETH_DEBUG+    if(pPortCtrl->portState != MV_ACTIVE)+        return MV_BAD_STATE;+#endif /* ETH_DEBUG */++    portNo = pPortCtrl->portNo;+    pQueueCtrl = &pPortCtrl->txQueue[txQueue];++    /* Get the Tx Desc ring indexes */+    pTxCurrDesc = pQueueCtrl->pCurrentDescr;++    /* Check if there is enough resources to send the packet */+    if(pQueueCtrl->resource == 0)+        return MV_NO_RESOURCE;++    pTxCurrDesc->byteCnt = pBufInfo->dataSize;++    /* Flash Buffer */+    if(pPktInfo->pktSize != 0)+    {+#ifdef MV_NETBSD+        pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;+        ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);+#else+        pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);+#endif+        pPktInfo->pktSize = 0;+    }+    else+        pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;++    pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;++    /* There is only one buffer in the packet */+    /* The OSG might set some bits for checksum offload, so add them to first descriptor */+    pTxCurrDesc->cmdSts = pPktInfo->status              |+                          ETH_BUFFER_OWNED_BY_DMA       |+                          ETH_TX_GENERATE_CRC_MASK      |+                          ETH_TX_ENABLE_INTERRUPT_MASK  |+                          ETH_TX_ZERO_PADDING_MASK      |+                          ETH_TX_FIRST_DESC_MASK        |+                          ETH_TX_LAST_DESC_MASK;++    ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);++    pQueueCtrl->resource--;+    pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);++    /* Apply send command */+    MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;++    return MV_OK;+}+++/*******************************************************************************+* mvEthPortSgTx - Send an Ethernet packet+*+* DESCRIPTION:+*       This routine send a given packet described by pBufInfo parameter. It+*       supports transmitting of a packet spaned over multiple buffers. +*+* INPUT:+*       void*       pEthPortHndl  - Ethernet Port handler.+*       int         txQueue       - Number of Tx queue.+*       MV_PKT_INFO *pPktInfo     - User packet to send.+*+* RETURN:+*       MV_NO_RESOURCE  - No enough resources to send this packet.+*       MV_ERROR        - Unexpected Fatal error.+*       MV_OK           - Packet send successfully.+*+*******************************************************************************/+static INLINE MV_STATUS   mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)+{+    ETH_TX_DESC*    pTxFirstDesc;+    ETH_TX_DESC*    pTxCurrDesc;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl;+    int             portNo, bufCount;+    MV_BUF_INFO*    pBufInfo = pPktInfo->pFrags;+    MV_U8*          pTxBuf;++#ifdef ETH_DEBUG+    if(pPortCtrl->portState != MV_ACTIVE)+        return MV_BAD_STATE;+#endif /* ETH_DEBUG */++    portNo = pPortCtrl->portNo;+    pQueueCtrl = &pPortCtrl->txQueue[txQueue];++    /* Get the Tx Desc ring indexes */+    pTxCurrDesc = pQueueCtrl->pCurrentDescr;++    /* Check if there is enough resources to send the packet */+    if(pQueueCtrl->resource < pPktInfo->numFrags)+        return MV_NO_RESOURCE;++    /* Remember first desc */+    pTxFirstDesc  = pTxCurrDesc;++    bufCount = 0;+    while(MV_TRUE)+    {   +        if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)+        {+            /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned    */+            /* to 64-bit boundary. Two options here:                                             */+            /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor.           */+            /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */ +            /*    as a pointer to the aligned buffer, copy the small payload to this buffer.     */+            pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;+            mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);+            pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);+        }+        else+        {+            /* Flash Buffer */+#ifdef MV_NETBSD+            pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;+	    ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);+#else+            pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);+#endif+        }++        pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;+        bufCount++;++        if(bufCount >= pPktInfo->numFrags)+            break;++        if(bufCount > 1)+        {+            /* There is middle buffer of the packet Not First and Not Last */+            pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;+            ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);+        }+        /* Go to next descriptor and next buffer */+        pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);+    }+    /* Set last desc with DMA ownership and interrupt enable. */+    pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;+    if(bufCount == 1) +    {+        /* There is only one buffer in the packet */+        /* The OSG might set some bits for checksum offload, so add them to first descriptor */+        pTxCurrDesc->cmdSts = pPktInfo->status              |+                              ETH_BUFFER_OWNED_BY_DMA       |+                              ETH_TX_GENERATE_CRC_MASK      |+                              ETH_TX_ENABLE_INTERRUPT_MASK  |+                              ETH_TX_ZERO_PADDING_MASK      |+                              ETH_TX_FIRST_DESC_MASK        |+                              ETH_TX_LAST_DESC_MASK;++        ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);+    }+    else+    {+        /* Last but not First */+        pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA       |+                              ETH_TX_ENABLE_INTERRUPT_MASK  |+                              ETH_TX_ZERO_PADDING_MASK      |+                              ETH_TX_LAST_DESC_MASK;++        ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);++        /* Update First when more than one buffer in the packet */+        /* The OSG might set some bits for checksum offload, so add them to first descriptor */+        pTxFirstDesc->cmdSts = pPktInfo->status             |+                               ETH_BUFFER_OWNED_BY_DMA      |+                               ETH_TX_GENERATE_CRC_MASK     |+                               ETH_TX_FIRST_DESC_MASK;++        ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);+    }+    /* Update txQueue state */+    pQueueCtrl->resource -= bufCount;+    pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);++    /* Apply send command */+    MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;++    return MV_OK;+}++/*******************************************************************************+* mvEthPortTxDone - Free all used Tx descriptors and mBlks.+*+* DESCRIPTION:+*       This routine returns the transmitted packet information to the caller.+*+* INPUT:+*       void*       pEthPortHndl    - Ethernet Port handler.+*       int         txQueue         - Number of Tx queue.+*+* OUTPUT:+*       MV_PKT_INFO *pPktInfo       - Pointer to packet was sent.+*+* RETURN:+*       MV_NOT_FOUND    - No transmitted packets to return. Transmit in progress.+*       MV_EMPTY        - No transmitted packets to return. TX Queue is empty.+*       MV_ERROR        - Unexpected Fatal error.+*       MV_OK           - There is transmitted packet in the queue, +*                       'pPktInfo' filled with relevant information.+*+*******************************************************************************/+static INLINE MV_PKT_INFO*    mvEthPortTxDone(void* pEthPortHndl, int txQueue)+{+    ETH_TX_DESC*    pTxCurrDesc;+    ETH_TX_DESC*    pTxUsedDesc;+    ETH_QUEUE_CTRL* pQueueCtrl;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    MV_PKT_INFO*    pPktInfo;+    MV_U32          commandStatus;++    pQueueCtrl = &pPortCtrl->txQueue[txQueue];++    pTxUsedDesc = pQueueCtrl->pUsedDescr;+    pTxCurrDesc = pQueueCtrl->pCurrentDescr;++    while(MV_TRUE)+    {+        /* No more used descriptors */+        commandStatus = pTxUsedDesc->cmdSts;+        if (commandStatus  & (ETH_BUFFER_OWNED_BY_DMA))+        {    +            ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);+            return NULL;+        }+        if( (pTxUsedDesc == pTxCurrDesc) &&+            (pQueueCtrl->resource != 0) )+        {+            return NULL;+        }+        pQueueCtrl->resource++;+        pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);+        if(commandStatus & (ETH_TX_LAST_DESC_MASK)) +        {+            pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;+            pPktInfo->status  = commandStatus;            +            return pPktInfo;+        }+        pTxUsedDesc = pQueueCtrl->pUsedDescr;+    }+}++/*******************************************************************************+* mvEthPortRx - Get new received packets from Rx queue.+*+* DESCRIPTION:+*       This routine returns the received data to the caller. There is no+*       data copying during routine operation. All information is returned+*       using pointer to packet information struct passed from the caller.+*+* INPUT:+*       void*       pEthPortHndl    - Ethernet Port handler.+*       int         rxQueue         - Number of Rx queue.+*+* OUTPUT:+*       MV_PKT_INFO *pPktInfo       - Pointer to received packet.+*+* RETURN:+*       MV_NO_RESOURCE  - No free resources in RX queue.+*       MV_ERROR        - Unexpected Fatal error.+*       MV_OK           - New packet received and 'pBufInfo' structure filled+*                       with relevant information.+*+*******************************************************************************/+static INLINE MV_PKT_INFO*    mvEthPortRx(void* pEthPortHndl, int rxQueue)+{+    ETH_RX_DESC     *pRxCurrDesc;+    MV_U32          commandStatus;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+    ETH_QUEUE_CTRL* pQueueCtrl;+    MV_PKT_INFO*    pPktInfo;++    pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);++    /* Check resources */+    if(pQueueCtrl->resource == 0)+    {+        mvOsPrintf("ethPortRx: no more resources\n");+        return NULL;+    }+    while(MV_TRUE)+    {+        /* Get the Rx Desc ring 'curr and 'used' indexes */+        pRxCurrDesc = pQueueCtrl->pCurrentDescr;++	commandStatus   = pRxCurrDesc->cmdSts;+        if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))+        {+            /* Nothing to receive... */+            ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);+            return NULL;+        }++        /* Valid RX only if FIRST and LAST bits are set */+        if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) == +                             (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )+        {+            pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;+            pPktInfo->pFrags->dataSize  = pRxCurrDesc->byteCnt - 4;+            pPktInfo->status            = commandStatus;+            pPktInfo->fragIP            = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;++            pQueueCtrl->resource--;+            /* Update 'curr' in data structure */+            pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);++#ifdef INCLUDE_SYNC_BARR+            mvCpuIfSyncBarr(DRAM_TARGET);+#endif+            return pPktInfo;+        }+        else+        {+            ETH_RX_DESC*    pRxUsedDesc = pQueueCtrl->pUsedDescr;++#ifdef ETH_DEBUG+            mvOsPrintf("ethDrv: Unexpected Jumbo frame: "+                       "status=0x%08x, byteCnt=%d, pData=0x%x\n", +                        commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);+#endif /* ETH_DEBUG */++            /* move buffer from pCurrentDescr position to pUsedDescr position */+            pRxUsedDesc->bufPtr     = pRxCurrDesc->bufPtr;+            pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;+            pRxUsedDesc->bufSize    = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;++            /* Return the descriptor to DMA ownership */+            pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | +                                  ETH_RX_ENABLE_INTERRUPT_MASK;++            /* Flush descriptor and CPU pipe */+            ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);++            /* Move the used descriptor pointer to the next descriptor */+            pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);+            pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);            +        }+    }+}++/*******************************************************************************+* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.+*+* DESCRIPTION:+*       This routine returns a Rx buffer back to the Rx ring. +*+* INPUT:+*       void*       pEthPortHndl    - Ethernet Port handler.+*       int         rxQueue         - Number of Rx queue.+*       MV_PKT_INFO *pPktInfo       - Pointer to received packet.+*+* RETURN:+*       MV_ERROR        - Unexpected Fatal error.+*       MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be +*                       returned to this queue.+*       MV_FULL         - Buffer returned successfully and RX queue became full.+*                       More buffers should not be returned at the time.+*       MV_OK           - Buffer returned successfully and there are more free +*                       places in the queue.+*+*******************************************************************************/+static INLINE MV_STATUS   mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)+{+    ETH_RX_DESC*    pRxUsedDesc;+    ETH_QUEUE_CTRL* pQueueCtrl;+    ETH_PORT_CTRL*  pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;+            +    pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];++    /* Get 'used' Rx descriptor */+    pRxUsedDesc = pQueueCtrl->pUsedDescr;++    /* Check that ring is not FULL */+    if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) && +        (pQueueCtrl->resource != 0) )+    {+        mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n", +                    __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource, +                    pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);+        return MV_OUT_OF_RANGE;+    }++    pRxUsedDesc->bufPtr     = pPktInfo->pFrags->bufPhysAddr;+    pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;+    pRxUsedDesc->bufSize    = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;++    /* Invalidate data buffer accordingly with pktSize */+    if(pPktInfo->pktSize != 0)+    {+        ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);+        pPktInfo->pktSize = 0;+    }++    /* Return the descriptor to DMA ownership */+    pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;++    /* Flush descriptor and CPU pipe */+    ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);++    pQueueCtrl->resource++;++    /* Move the used descriptor pointer to the next descriptor */+    pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);+    +    /* If ring became Full return MV_FULL */+    if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) +        return MV_FULL;++    return MV_OK;+}+++#endif /* __mvEthGbe_h__ */++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h	2010-11-09 20:28:11.192495435 +0100@@ -0,0 +1,700 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+        this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCmvEthRegsh+#define __INCmvEthRegsh++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++#include "ctrlEnv/mvCtrlEnvSpec.h"++/****************************************/+/*        Ethernet Unit Registers       */+/****************************************/+#define ETH_REG_BASE 					MV_ETH_REG_BASE++#define ETH_PHY_ADDR_REG(port)              (ETH_REG_BASE(port) + 0x000)+#define ETH_SMI_REG(port)                   (ETH_REG_BASE(port) + 0x004)+#define ETH_UNIT_DEF_ADDR_REG(port)         (ETH_REG_BASE(port) + 0x008)+#define ETH_UNIT_DEF_ID_REG(port)           (ETH_REG_BASE(port) + 0x00c)+#define ETH_UNIT_RESERVED(port)             (ETH_REG_BASE(port) + 0x014)+#define ETH_UNIT_INTR_CAUSE_REG(port)       (ETH_REG_BASE(port) + 0x080)+#define ETH_UNIT_INTR_MASK_REG(port)        (ETH_REG_BASE(port) + 0x084)+++#define ETH_UNIT_ERROR_ADDR_REG(port)       (ETH_REG_BASE(port) + 0x094)+#define ETH_UNIT_INT_ADDR_ERROR_REG(port)   (ETH_REG_BASE(port) + 0x098)+#define ETH_UNIT_CONTROL_REG(port)          (ETH_REG_BASE(port) + 0x0B0)++#define ETH_PORT_CONFIG_REG(port)           (ETH_REG_BASE(port) + 0x400)+#define ETH_PORT_CONFIG_EXTEND_REG(port)    (ETH_REG_BASE(port) + 0x404)+#define ETH_MII_SERIAL_PARAM_REG(port)      (ETH_REG_BASE(port) + 0x408)+#define ETH_GMII_SERIAL_PARAM_REG(port)     (ETH_REG_BASE(port) + 0x40c)+#define ETH_VLAN_ETHER_TYPE_REG(port)       (ETH_REG_BASE(port) + 0x410)+#define ETH_MAC_ADDR_LOW_REG(port)          (ETH_REG_BASE(port) + 0x414)+#define ETH_MAC_ADDR_HIGH_REG(port)         (ETH_REG_BASE(port) + 0x418)+#define ETH_SDMA_CONFIG_REG(port)           (ETH_REG_BASE(port) + 0x41c)+#define ETH_DIFF_SERV_PRIO_REG(port, code)  (ETH_REG_BASE(port) + 0x420  + ((code)<<2))+#define ETH_PORT_SERIAL_CTRL_REG(port)      (ETH_REG_BASE(port) + 0x43c)+#define ETH_VLAN_TAG_TO_PRIO_REG(port)      (ETH_REG_BASE(port) + 0x440)+#define ETH_PORT_STATUS_REG(port)           (ETH_REG_BASE(port) + 0x444)++#define ETH_RX_QUEUE_COMMAND_REG(port)      (ETH_REG_BASE(port) + 0x680)+#define ETH_TX_QUEUE_COMMAND_REG(port)      (ETH_REG_BASE(port) + 0x448)++#define ETH_PORT_SERIAL_CTRL_1_REG(port)    (ETH_REG_BASE(port) + 0x44c)+#define ETH_PORT_STATUS_1_REG(port)         (ETH_REG_BASE(port) + 0x450)+#define ETH_PORT_MARVELL_HEADER_REG(port)   (ETH_REG_BASE(port) + 0x454)+#define ETH_PORT_FIFO_PARAMS_REG(port)      (ETH_REG_BASE(port) + 0x458)+#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)+#define ETH_INTR_CAUSE_REG(port)            (ETH_REG_BASE(port) + 0x460)+#define ETH_INTR_CAUSE_EXT_REG(port)        (ETH_REG_BASE(port) + 0x464)+#define ETH_INTR_MASK_REG(port)             (ETH_REG_BASE(port) + 0x468)+#define ETH_INTR_MASK_EXT_REG(port)         (ETH_REG_BASE(port) + 0x46c)+#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)+#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)+#define ETH_RX_DISCARD_PKTS_CNTR_REG(port)  (ETH_REG_BASE(port) + 0x484)+#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port)  (ETH_REG_BASE(port) + 0x488)+#define ETH_INTERNAL_ADDR_ERROR_REG(port)   (ETH_REG_BASE(port) + 0x494)+#define ETH_TX_FIXED_PRIO_CFG_REG(port)     (ETH_REG_BASE(port) + 0x4dc)+#define ETH_TX_TOKEN_RATE_CFG_REG(port)     (ETH_REG_BASE(port) + 0x4e0)+#define ETH_TX_QUEUE_COMMAND1_REG(port)     (ETH_REG_BASE(port) + 0x4e4)+#define ETH_MAX_TRANSMIT_UNIT_REG(port)     (ETH_REG_BASE(port) + 0x4e8)+#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port)  (ETH_REG_BASE(port) + 0x4ec)+#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)+#define ETH_RX_DESCR_STAT_CMD_REG(port, q)  (ETH_REG_BASE(port) + 0x600 + ((q)<<4))+#define ETH_RX_BYTE_COUNT_REG(port, q)      (ETH_REG_BASE(port) + 0x604 + ((q)<<4))+#define ETH_RX_BUF_PTR_REG(port, q)         (ETH_REG_BASE(port) + 0x608 + ((q)<<4))+#define ETH_RX_CUR_DESC_PTR_REG(port, q)    (ETH_REG_BASE(port) + 0x60c + ((q)<<4))+#define ETH_TX_CUR_DESC_PTR_REG(port, q)    (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))++#define ETH_TXQ_TOKEN_COUNT_REG(port, q)    (ETH_REG_BASE(port) + 0x700 + ((q)<<4))+#define ETH_TXQ_TOKEN_CFG_REG(port, q)      (ETH_REG_BASE(port) + 0x704 + ((q)<<4))+#define ETH_TXQ_ARBITER_CFG_REG(port, q)    (ETH_REG_BASE(port) + 0x708 + ((q)<<4))++#if (MV_ETH_VERSION >= 4) +#define ETH_TXQ_CMD_1_REG(port)             (ETH_REG_BASE(port) + 0x4E4)+#define ETH_EJP_TX_HI_IPG_REG(port)         (ETH_REG_BASE(port) + 0x7A8)+#define ETH_EJP_TX_LO_IPG_REG(port)         (ETH_REG_BASE(port) + 0x7B8)+#define ETH_EJP_HI_TKN_LO_PKT_REG(port)     (ETH_REG_BASE(port) + 0x7C0)+#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port)  (ETH_REG_BASE(port) + 0x7C4)+#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port)  (ETH_REG_BASE(port) + 0x7C8)+#define ETH_EJP_TX_SPEED_REG(port)          (ETH_REG_BASE(port) + 0x7D0)+#endif /* MV_ETH_VERSION >= 4 */++#define ETH_MIB_COUNTERS_BASE(port)         (ETH_REG_BASE(port) + 0x1000)+#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)+#define ETH_DA_FILTER_OTH_MCAST_BASE(port)  (ETH_REG_BASE(port) + 0x1500)+#define ETH_DA_FILTER_UCAST_BASE(port)      (ETH_REG_BASE(port) + 0x1600)++/* Phy address register definitions */+#define ETH_PHY_ADDR_OFFS          0                                       +#define ETH_PHY_ADDR_MASK          (0x1f <<ETH_PHY_ADDR_OFFS)+                                 +/* MIB Counters register definitions */+#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW    0x0+#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH   0x4+#define ETH_MIB_BAD_OCTETS_RECEIVED         0x8+#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR   0xc+#define ETH_MIB_GOOD_FRAMES_RECEIVED        0x10+#define ETH_MIB_BAD_FRAMES_RECEIVED         0x14+#define ETH_MIB_BROADCAST_FRAMES_RECEIVED   0x18+#define ETH_MIB_MULTICAST_FRAMES_RECEIVED   0x1c+#define ETH_MIB_FRAMES_64_OCTETS            0x20+#define ETH_MIB_FRAMES_65_TO_127_OCTETS     0x24+#define ETH_MIB_FRAMES_128_TO_255_OCTETS    0x28+#define ETH_MIB_FRAMES_256_TO_511_OCTETS    0x2c+#define ETH_MIB_FRAMES_512_TO_1023_OCTETS   0x30+#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS   0x34+#define ETH_MIB_GOOD_OCTETS_SENT_LOW        0x38+#define ETH_MIB_GOOD_OCTETS_SENT_HIGH       0x3c+#define ETH_MIB_GOOD_FRAMES_SENT            0x40+#define ETH_MIB_EXCESSIVE_COLLISION         0x44+#define ETH_MIB_MULTICAST_FRAMES_SENT       0x48+#define ETH_MIB_BROADCAST_FRAMES_SENT       0x4c+#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED  0x50+#define ETH_MIB_FC_SENT                     0x54+#define ETH_MIB_GOOD_FC_RECEIVED            0x58+#define ETH_MIB_BAD_FC_RECEIVED             0x5c+#define ETH_MIB_UNDERSIZE_RECEIVED          0x60+#define ETH_MIB_FRAGMENTS_RECEIVED          0x64+#define ETH_MIB_OVERSIZE_RECEIVED           0x68+#define ETH_MIB_JABBER_RECEIVED             0x6c+#define ETH_MIB_MAC_RECEIVE_ERROR           0x70+#define ETH_MIB_BAD_CRC_EVENT               0x74+#define ETH_MIB_COLLISION                   0x78+#define ETH_MIB_LATE_COLLISION              0x7c+++/****************************************/+/*        Ethernet Unit Register BITs   */+/****************************************/++#define ETH_RXQ_ENABLE_OFFSET               0+#define ETH_RXQ_ENABLE_MASK                 (0x000000FF << ETH_RXQ_ENABLE_OFFSET)++#define ETH_RXQ_DISABLE_OFFSET              8+#define ETH_RXQ_DISABLE_MASK                (0x000000FF << ETH_RXQ_DISABLE_OFFSET)++/***** BITs of Transmit Queue Command (TQC) register *****/+#define ETH_TXQ_ENABLE_OFFSET               0+#define ETH_TXQ_ENABLE_MASK                 (0x000000FF << ETH_TXQ_ENABLE_OFFSET)++#define ETH_TXQ_DISABLE_OFFSET              8+#define ETH_TXQ_DISABLE_MASK                (0x000000FF << ETH_TXQ_DISABLE_OFFSET)++#if (MV_ETH_VERSION >= 4) +#define ETH_TX_EJP_RESET_BIT                0+#define ETH_TX_EJP_RESET_MASK               (1 << ETH_TX_EJP_RESET_BIT)++#define ETH_TX_EJP_ENABLE_BIT               2+#define ETH_TX_EJP_ENABLE_MASK              (1 << ETH_TX_EJP_ENABLE_BIT)++#define ETH_TX_LEGACY_WRR_BIT               3+#define ETH_TX_LEGACY_WRR_MASK              (1 << ETH_TX_LEGACY_WRR_BIT)+#endif /* (MV_ETH_VERSION >= 4) */++/***** BITs of Ethernet Port Status reg (PSR) *****/+#define ETH_LINK_UP_BIT                     1+#define ETH_LINK_UP_MASK                    (1<<ETH_LINK_UP_BIT)+                     +#define ETH_FULL_DUPLEX_BIT                 2+#define ETH_FULL_DUPLEX_MASK                (1<<ETH_FULL_DUPLEX_BIT)++#define ETH_ENABLE_RCV_FLOW_CTRL_BIT        3+#define ETH_ENABLE_RCV_FLOW_CTRL_MASK       (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)++#define ETH_GMII_SPEED_1000_BIT             4+#define ETH_GMII_SPEED_1000_MASK            (1<<ETH_GMII_SPEED_1000_BIT)++#define ETH_MII_SPEED_100_BIT               5+#define ETH_MII_SPEED_100_MASK              (1<<ETH_MII_SPEED_100_BIT)++#define ETH_TX_IN_PROGRESS_BIT              7+#define ETH_TX_IN_PROGRESS_MASK             (1<<ETH_TX_IN_PROGRESS_BIT)++#define ETH_TX_FIFO_EMPTY_BIT               10+#define ETH_TX_FIFO_EMPTY_MASK              (1<<ETH_TX_FIFO_EMPTY_BIT)++/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/+#define ETH_AUTO_NEG_DONE_BIT               4+#define ETH_AUTO_NEG_DONE_MASK              (1<<ETH_AUTO_NEG_DONE_BIT)++#define ETH_SERDES_PLL_LOCKED_BIT           6+#define ETH_SERDES_PLL_LOCKED_MASK          (1<<ETH_SERDES_PLL_LOCKED_BIT)++/***** BITs of Port Configuration reg (PxCR) *****/+#define ETH_UNICAST_PROMISCUOUS_MODE_BIT    0+#define ETH_UNICAST_PROMISCUOUS_MODE_MASK   (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)++#define ETH_DEF_RX_QUEUE_OFFSET             1+#define ETH_DEF_RX_QUEUE_ALL_MASK           (0x7<<ETH_DEF_RX_QUEUE_OFFSET)+#define ETH_DEF_RX_QUEUE_MASK(queue)        ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)++#define ETH_DEF_RX_ARP_QUEUE_OFFSET         4+#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK       (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)+#define ETH_DEF_RX_ARP_QUEUE_MASK(queue)    ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)++#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT     7+#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK    (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)++#define ETH_REJECT_IP_BCAST_BIT             8+#define ETH_REJECT_IP_BCAST_MASK            (1<<ETH_REJECT_IP_BCAST_BIT)++#define ETH_REJECT_ARP_BCAST_BIT            9+#define ETH_REJECT_ARP_BCAST_MASK           (1<<ETH_REJECT_ARP_BCAST_BIT)++#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT     12+#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK    (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)++#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT   14+#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK  (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)++#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT   15+#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK  (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)++#define ETH_DEF_RX_TCP_QUEUE_OFFSET         16+#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK       (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)+#define ETH_DEF_RX_TCP_QUEUE_MASK(queue)    ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)++#define ETH_DEF_RX_UDP_QUEUE_OFFSET         19+#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK       (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)+#define ETH_DEF_RX_UDP_QUEUE_MASK(queue)    ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)++#define ETH_DEF_RX_BPDU_QUEUE_OFFSET        22+#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK      (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)+#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue)   ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)++#define ETH_RX_CHECKSUM_MODE_OFFSET         25+#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR       (0<<ETH_RX_CHECKSUM_MODE_OFFSET)+#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR     (1<<ETH_RX_CHECKSUM_MODE_OFFSET)++/***** BITs of Port Configuration Extend reg (PxCXR) *****/+#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT    1+#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK   (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)++#define ETH_TX_DISABLE_GEN_CRC_BIT          3+#define ETH_TX_DISABLE_GEN_CRC_MASK         (1<<ETH_TX_DISABLE_GEN_CRC_BIT)++/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/+#define ETH_QUEUE_ENABLE_OFFSET             0+#define ETH_QUEUE_ENABLE_ALL_MASK           (0xFF<<ETH_QUEUE_ENABLE_OFFSET)+#define ETH_QUEUE_ENABLE_MASK(queue)        (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))++#define ETH_QUEUE_DISABLE_OFFSET            8 +#define ETH_QUEUE_DISABLE_ALL_MASK          (0xFF<<ETH_QUEUE_DISABLE_OFFSET)+#define ETH_QUEUE_DISABLE_MASK(queue)       (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))+++/***** BITs of Port Sdma Configuration reg (SDCR) *****/+#define ETH_RX_FRAME_INTERRUPT_BIT          0+#define ETH_RX_FRAME_INTERRUPT_MASK         (1<<ETH_RX_FRAME_INTERRUPT_BIT)++#define ETH_BURST_SIZE_1_64BIT_VALUE        0   +#define ETH_BURST_SIZE_2_64BIT_VALUE        1+#define ETH_BURST_SIZE_4_64BIT_VALUE        2+#define ETH_BURST_SIZE_8_64BIT_VALUE        3+#define ETH_BURST_SIZE_16_64BIT_VALUE       4++#define ETH_RX_BURST_SIZE_OFFSET            1+#define ETH_RX_BURST_SIZE_ALL_MASK          (0x7<<ETH_RX_BURST_SIZE_OFFSET)+#define ETH_RX_BURST_SIZE_MASK(burst)       ((burst)<<ETH_RX_BURST_SIZE_OFFSET)++#define ETH_RX_NO_DATA_SWAP_BIT             4+#define ETH_RX_NO_DATA_SWAP_MASK            (1<<ETH_RX_NO_DATA_SWAP_BIT)+#define ETH_RX_DATA_SWAP_MASK               (0<<ETH_RX_NO_DATA_SWAP_BIT)++#define ETH_TX_NO_DATA_SWAP_BIT             5+#define ETH_TX_NO_DATA_SWAP_MASK            (1<<ETH_TX_NO_DATA_SWAP_BIT)+#define ETH_TX_DATA_SWAP_MASK               (0<<ETH_TX_NO_DATA_SWAP_BIT)++#define ETH_DESC_SWAP_BIT                   6+#define ETH_DESC_SWAP_MASK                  (1<<ETH_DESC_SWAP_BIT)+#define ETH_NO_DESC_SWAP_MASK               (0<<ETH_DESC_SWAP_BIT)++#define ETH_RX_INTR_COAL_OFFSET             7+#define ETH_RX_INTR_COAL_ALL_MASK           (0x3fff<<ETH_RX_INTR_COAL_OFFSET)+#define ETH_RX_INTR_COAL_MASK(value)        (((value)<<ETH_RX_INTR_COAL_OFFSET)  \+                                             & ETH_RX_INTR_COAL_ALL_MASK)++#define ETH_TX_BURST_SIZE_OFFSET            22+#define ETH_TX_BURST_SIZE_ALL_MASK          (0x7<<ETH_TX_BURST_SIZE_OFFSET)+#define ETH_TX_BURST_SIZE_MASK(burst)       ((burst)<<ETH_TX_BURST_SIZE_OFFSET)++#define ETH_RX_INTR_COAL_MSB_BIT            25+#define ETH_RX_INTR_COAL_MSB_MASK           (1<<ETH_RX_INTR_COAL_MSB_BIT)  ++/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */+#define ETH_TX_INTR_COAL_OFFSET             4+#define ETH_TX_INTR_COAL_ALL_MASK           (0x3fff << ETH_TX_INTR_COAL_OFFSET)+#define ETH_TX_INTR_COAL_MASK(value)        (((value) << ETH_TX_INTR_COAL_OFFSET)  \+                                             & ETH_TX_INTR_COAL_ALL_MASK)++/* BITs of Port Serial Control reg (PSCR) */+#define ETH_PORT_ENABLE_BIT                 0+#define ETH_PORT_ENABLE_MASK                (1<<ETH_PORT_ENABLE_BIT)++#define ETH_FORCE_LINK_PASS_BIT             1+#define ETH_FORCE_LINK_PASS_MASK            (1<<ETH_FORCE_LINK_PASS_BIT)++#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT     2+#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK    (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)++#define ETH_DISABLE_FC_AUTO_NEG_BIT         3+#define ETH_DISABLE_FC_AUTO_NEG_MASK        (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)++#define ETH_ADVERTISE_SYM_FC_BIT            4+#define ETH_ADVERTISE_SYM_FC_MASK           (1<<ETH_ADVERTISE_SYM_FC_BIT)++#define ETH_TX_FC_MODE_OFFSET               5+#define ETH_TX_FC_MODE_MASK                 (3<<ETH_TX_FC_MODE_OFFSET)+#define ETH_TX_FC_NO_PAUSE                  (0<<ETH_TX_FC_MODE_OFFSET)+#define ETH_TX_FC_SEND_PAUSE                (1<<ETH_TX_FC_MODE_OFFSET)++#define ETH_TX_BP_MODE_OFFSET               7+#define ETH_TX_BP_MODE_MASK                 (3<<ETH_TX_BP_MODE_OFFSET)+#define ETH_TX_BP_NO_JAM                    (0<<ETH_TX_BP_MODE_OFFSET)+#define ETH_TX_BP_SEND_JAM                  (1<<ETH_TX_BP_MODE_OFFSET)++#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT      10+#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK     (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)++#define ETH_RETRANSMIT_FOREVER_BIT          11+#define ETH_RETRANSMIT_FOREVER_MASK         (1<<ETH_RETRANSMIT_FOREVER_BIT)++#define ETH_DISABLE_SPEED_AUTO_NEG_BIT      13+#define ETH_DISABLE_SPEED_AUTO_NEG_MASK     (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)++#define ETH_DTE_ADVERT_BIT                  14    +#define ETH_DTE_ADVERT_MASK                 (1<<ETH_DTE_ADVERT_BIT)    ++#define ETH_MII_PHY_MODE_BIT                15  +#define ETH_MII_PHY_MODE_MAC                (0<<ETH_MII_PHY_MODE_BIT)+#define ETH_MII_PHY_MODE_PHY                (1<<ETH_MII_PHY_MODE_BIT)++#define ETH_MII_SOURCE_SYNCH_BIT            16+#define ETH_MII_STANDARD_SYNCH              (0<<ETH_MII_SOURCE_SYNCH_BIT)+#define ETH_MII_400Mbps_SYNCH               (1<<ETH_MII_SOURCE_CLK_BIT)++#define ETH_MAX_RX_PACKET_SIZE_OFFSET       17+#define ETH_MAX_RX_PACKET_SIZE_MASK         (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)+#define ETH_MAX_RX_PACKET_1518BYTE          (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)+#define ETH_MAX_RX_PACKET_1522BYTE          (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)+#define ETH_MAX_RX_PACKET_1552BYTE          (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)+#define ETH_MAX_RX_PACKET_9022BYTE          (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)+#define ETH_MAX_RX_PACKET_9192BYTE          (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)+#define ETH_MAX_RX_PACKET_9700BYTE          (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)++#define ETH_SET_FULL_DUPLEX_BIT             21+#define ETH_SET_FULL_DUPLEX_MASK            (1<<ETH_SET_FULL_DUPLEX_BIT)++#define ETH_SET_FLOW_CTRL_BIT               22+#define ETH_SET_FLOW_CTRL_MASK              (1<<ETH_SET_FLOW_CTRL_BIT)++#define ETH_SET_GMII_SPEED_1000_BIT         23+#define ETH_SET_GMII_SPEED_1000_MASK        (1<<ETH_SET_GMII_SPEED_1000_BIT)++#define ETH_SET_MII_SPEED_100_BIT           24+#define ETH_SET_MII_SPEED_100_MASK          (1<<ETH_SET_MII_SPEED_100_BIT)++/* BITs of Port Serial Control 1 reg (PSC1R) */+#define ETH_PSC_ENABLE_BIT                  2+#define ETH_PSC_ENABLE_MASK                 (1<<ETH_PSC_ENABLE_BIT)++#define ETH_RGMII_ENABLE_BIT                3+#define ETH_RGMII_ENABLE_MASK               (1<<ETH_RGMII_ENABLE_BIT)++#define ETH_PORT_RESET_BIT                  4+#define ETH_PORT_RESET_MASK                 (1<<ETH_PORT_RESET_BIT)++#define ETH_INBAND_AUTO_NEG_ENABLE_BIT      6+#define ETH_INBAND_AUTO_NEG_ENABLE_MASK     (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)++#define ETH_INBAND_AUTO_NEG_BYPASS_BIT      7+#define ETH_INBAND_AUTO_NEG_BYPASS_MASK     (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)++#define ETH_INBAND_AUTO_NEG_START_BIT       8+#define ETH_INBAND_AUTO_NEG_START_MASK      (1<<ETH_INBAND_AUTO_NEG_START_BIT)++#define ETH_PORT_TYPE_BIT                   11+#define ETH_PORT_TYPE_1000BasedX_MASK       (1<<ETH_PORT_TYPE_BIT)++#define ETH_SGMII_MODE_BIT                  12+#define ETH_1000BaseX_MODE_MASK             (0<<ETH_SGMII_MODE_BIT)+#define ETH_SGMII_MODE_MASK                 (1<<ETH_SGMII_MODE_BIT)+            +#define ETH_MGMII_MODE_BIT                  13++#define ETH_EN_MII_ODD_PRE_BIT		    22+#define ETH_EN_MII_ODD_PRE_MASK		    (1<<ETH_EN_MII_ODD_PRE_BIT)++/* BITs of SDMA Descriptor Command/Status field */+#if defined(MV_CPU_BE)+typedef struct _ethRxDesc+{+    MV_U16      byteCnt    ;    /* Descriptor buffer byte count     */+    MV_U16      bufSize    ;    /* Buffer size                      */+    MV_U32      cmdSts     ;    /* Descriptor command status        */+    MV_U32      nextDescPtr;    /* Next descriptor pointer          */+    MV_U32      bufPtr     ;    /* Descriptor buffer pointer        */+    MV_ULONG    returnInfo ;    /* User resource return information */+} ETH_RX_DESC;++typedef struct _ethTxDesc+{+    MV_U16      byteCnt    ;    /* Descriptor buffer byte count     */+    MV_U16      L4iChk     ;    /* CPU provided TCP Checksum        */+    MV_U32      cmdSts     ;    /* Descriptor command status        */+    MV_U32      nextDescPtr;    /* Next descriptor pointer          */+    MV_U32      bufPtr     ;    /* Descriptor buffer pointer        */+    MV_ULONG    returnInfo ;    /* User resource return information */+    MV_U8*      alignBufPtr;    /* Pointer to 8 byte aligned buffer */+} ETH_TX_DESC;++#elif defined(MV_CPU_LE)++typedef struct _ethRxDesc+{+    MV_U32      cmdSts     ;    /* Descriptor command status        */+    MV_U16      bufSize    ;    /* Buffer size                      */+    MV_U16      byteCnt    ;    /* Descriptor buffer byte count     */+    MV_U32      bufPtr     ;    /* Descriptor buffer pointer        */+    MV_U32      nextDescPtr;    /* Next descriptor pointer          */+    MV_ULONG    returnInfo ;    /* User resource return information */+} ETH_RX_DESC;++typedef struct _ethTxDesc+{+    MV_U32      cmdSts     ;    /* Descriptor command status        */+    MV_U16      L4iChk     ;    /* CPU provided TCP Checksum        */+    MV_U16      byteCnt    ;    /* Descriptor buffer byte count     */+    MV_U32      bufPtr     ;    /* Descriptor buffer pointer        */+    MV_U32      nextDescPtr;    /* Next descriptor pointer          */+    MV_ULONG    returnInfo ;    /* User resource return information */+    MV_U8*      alignBufPtr;    /* Pointer to 32 byte aligned buffer */+} ETH_TX_DESC;++#else+#error "MV_CPU_BE or MV_CPU_LE must be defined"+#endif /* MV_CPU_BE || MV_CPU_LE */++/* Buffer offset from buffer pointer */+#define ETH_RX_BUF_OFFSET               0x2+++/* Tx & Rx descriptor bits */+#define ETH_ERROR_SUMMARY_BIT               0+#define ETH_ERROR_SUMMARY_MASK              (1<<ETH_ERROR_SUMMARY_BIT)++#define ETH_BUFFER_OWNER_BIT                31             +#define ETH_BUFFER_OWNED_BY_DMA             (1<<ETH_BUFFER_OWNER_BIT)+#define ETH_BUFFER_OWNED_BY_HOST            (0<<ETH_BUFFER_OWNER_BIT)++/* Tx descriptor bits */+#define ETH_TX_ERROR_CODE_OFFSET            1+#define ETH_TX_ERROR_CODE_MASK              (3<<ETH_TX_ERROR_CODE_OFFSET)+#define ETH_TX_LATE_COLLISION_ERROR         (0<<ETH_TX_ERROR_CODE_OFFSET)+#define ETH_TX_UNDERRUN_ERROR               (1<<ETH_TX_ERROR_CODE_OFFSET)+#define ETH_TX_EXCESSIVE_COLLISION_ERROR    (2<<ETH_TX_ERROR_CODE_OFFSET)++#define ETH_TX_LLC_SNAP_FORMAT_BIT          9+#define ETH_TX_LLC_SNAP_FORMAT_MASK         (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)++#define ETH_TX_IP_FRAG_BIT                  10+#define ETH_TX_IP_FRAG_MASK                 (1<<ETH_TX_IP_FRAG_BIT)+#define ETH_TX_IP_FRAG                      (0<<ETH_TX_IP_FRAG_BIT)+#define ETH_TX_IP_NO_FRAG                   (1<<ETH_TX_IP_FRAG_BIT)++#define ETH_TX_IP_HEADER_LEN_OFFSET         11+#define ETH_TX_IP_HEADER_LEN_ALL_MASK       (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)+#define ETH_TX_IP_HEADER_LEN_MASK(len)      ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)++#define ETH_TX_VLAN_TAGGED_FRAME_BIT        15+#define ETH_TX_VLAN_TAGGED_FRAME_MASK       (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)++#define ETH_TX_L4_TYPE_BIT                  16+#define ETH_TX_L4_TCP_TYPE                  (0<<ETH_TX_L4_TYPE_BIT)+#define ETH_TX_L4_UDP_TYPE                  (1<<ETH_TX_L4_TYPE_BIT)++#define ETH_TX_GENERATE_L4_CHKSUM_BIT       17+#define ETH_TX_GENERATE_L4_CHKSUM_MASK      (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)++#define ETH_TX_GENERATE_IP_CHKSUM_BIT       18+#define ETH_TX_GENERATE_IP_CHKSUM_MASK      (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)++#define ETH_TX_ZERO_PADDING_BIT             19+#define ETH_TX_ZERO_PADDING_MASK            (1<<ETH_TX_ZERO_PADDING_BIT)++#define ETH_TX_LAST_DESC_BIT                20+#define ETH_TX_LAST_DESC_MASK               (1<<ETH_TX_LAST_DESC_BIT)++#define ETH_TX_FIRST_DESC_BIT               21+#define ETH_TX_FIRST_DESC_MASK              (1<<ETH_TX_FIRST_DESC_BIT)++#define ETH_TX_GENERATE_CRC_BIT             22+#define ETH_TX_GENERATE_CRC_MASK            (1<<ETH_TX_GENERATE_CRC_BIT)++#define ETH_TX_ENABLE_INTERRUPT_BIT         23+#define ETH_TX_ENABLE_INTERRUPT_MASK        (1<<ETH_TX_ENABLE_INTERRUPT_BIT)++#define ETH_TX_AUTO_MODE_BIT                30+#define ETH_TX_AUTO_MODE_MASK               (1<<ETH_TX_AUTO_MODE_BIT)+++/* Rx descriptor bits */+#define ETH_RX_ERROR_CODE_OFFSET            1+#define ETH_RX_ERROR_CODE_MASK              (3<<ETH_RX_ERROR_CODE_OFFSET)+#define ETH_RX_CRC_ERROR                    (0<<ETH_RX_ERROR_CODE_OFFSET)+#define ETH_RX_OVERRUN_ERROR                (1<<ETH_RX_ERROR_CODE_OFFSET)+#define ETH_RX_MAX_FRAME_LEN_ERROR          (2<<ETH_RX_ERROR_CODE_OFFSET)+#define ETH_RX_RESOURCE_ERROR               (3<<ETH_RX_ERROR_CODE_OFFSET)++#define ETH_RX_L4_CHECKSUM_OFFSET           3+#define ETH_RX_L4_CHECKSUM_MASK             (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)++#define ETH_RX_VLAN_TAGGED_FRAME_BIT        19+#define ETH_RX_VLAN_TAGGED_FRAME_MASK       (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)++#define ETH_RX_BPDU_FRAME_BIT               20+#define ETH_RX_BPDU_FRAME_MASK              (1<<ETH_RX_BPDU_FRAME_BIT)++#define ETH_RX_L4_TYPE_OFFSET               21+#define ETH_RX_L4_TYPE_MASK                 (3<<ETH_RX_L4_TYPE_OFFSET)+#define ETH_RX_L4_TCP_TYPE                  (0<<ETH_RX_L4_TYPE_OFFSET)+#define ETH_RX_L4_UDP_TYPE                  (1<<ETH_RX_L4_TYPE_OFFSET)+#define ETH_RX_L4_OTHER_TYPE                (2<<ETH_RX_L4_TYPE_OFFSET)++#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT      23+#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK     (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)++#define ETH_RX_IP_FRAME_TYPE_BIT            24+#define ETH_RX_IP_FRAME_TYPE_MASK           (1<<ETH_RX_IP_FRAME_TYPE_BIT)++#define ETH_RX_IP_HEADER_OK_BIT             25+#define ETH_RX_IP_HEADER_OK_MASK            (1<<ETH_RX_IP_HEADER_OK_BIT)++#define ETH_RX_LAST_DESC_BIT                26+#define ETH_RX_LAST_DESC_MASK               (1<<ETH_RX_LAST_DESC_BIT)++#define ETH_RX_FIRST_DESC_BIT               27+#define ETH_RX_FIRST_DESC_MASK              (1<<ETH_RX_FIRST_DESC_BIT)++#define ETH_RX_UNKNOWN_DA_BIT               28+#define ETH_RX_UNKNOWN_DA_MASK              (1<<ETH_RX_UNKNOWN_DA_BIT)++#define ETH_RX_ENABLE_INTERRUPT_BIT         29+#define ETH_RX_ENABLE_INTERRUPT_MASK        (1<<ETH_RX_ENABLE_INTERRUPT_BIT)++#define ETH_RX_L4_CHECKSUM_OK_BIT           30+#define ETH_RX_L4_CHECKSUM_OK_MASK          (1<<ETH_RX_L4_CHECKSUM_OK_BIT)++/* Rx descriptor bufSize field */+#define ETH_RX_IP_FRAGMENTED_FRAME_BIT      2+#define ETH_RX_IP_FRAGMENTED_FRAME_MASK     (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)++#define ETH_RX_BUFFER_MASK                  0xFFF8+++/* Ethernet Cause Register BITs */+#define ETH_CAUSE_RX_READY_SUM_BIT          0+#define ETH_CAUSE_EXTEND_BIT                1++#define ETH_CAUSE_RX_READY_OFFSET           2+#define ETH_CAUSE_RX_READY_BIT(queue)       (ETH_CAUSE_RX_READY_OFFSET + (queue))+#define ETH_CAUSE_RX_READY_MASK(queue)      (1 << (ETH_CAUSE_RX_READY_BIT(queue))) ++#define ETH_CAUSE_RX_ERROR_SUM_BIT          10+#define ETH_CAUSE_RX_ERROR_OFFSET           11+#define ETH_CAUSE_RX_ERROR_BIT(queue)       (ETH_CAUSE_RX_ERROR_OFFSET + (queue))+#define ETH_CAUSE_RX_ERROR_MASK(queue)      (1 << (ETH_CAUSE_RX_ERROR_BIT(queue))) ++#define ETH_CAUSE_TX_END_BIT                19+#define ETH_CAUSE_SUM_BIT                   31++/* Ethernet Cause Extended Register BITs */+#define ETH_CAUSE_TX_BUF_OFFSET             0+#define ETH_CAUSE_TX_BUF_BIT(queue)         (ETH_CAUSE_TX_BUF_OFFSET + (queue))+#define ETH_CAUSE_TX_BUF_MASK(queue)        (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))+         +#define ETH_CAUSE_TX_ERROR_OFFSET           8+#define ETH_CAUSE_TX_ERROR_BIT(queue)       (ETH_CAUSE_TX_ERROR_OFFSET + (queue))+#define ETH_CAUSE_TX_ERROR_MASK(queue)      (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))++#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT     16+#define ETH_CAUSE_RX_OVERRUN_BIT            18          +#define ETH_CAUSE_TX_UNDERRUN_BIT           19+#define ETH_CAUSE_LINK_STATE_CHANGE_BIT     20+#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT     23+#define ETH_CAUSE_EXTEND_SUM_BIT            31++/* Marvell Header Register */+/* Marvell Header register bits */+#define ETH_MVHDR_EN_BIT                    0+#define ETH_MVHDR_EN_MASK                   (1 << ETH_MVHDR_EN_BIT)++#define ETH_MVHDR_DAPREFIX_BIT              1+#define ETH_MVHDR_DAPREFIX_MASK             (0x3 << ETH_MVHDR_DAPREFIX_BIT)+#define ETH_MVHDR_DAPREFIX_PRI_1_2          (0x1 << ETH_MVHDR_DAPREFIX_BIT)+#define ETH_MVHDR_DAPREFIX_DBNUM_PRI        (0x2 << ETH_MVHDR_DAPREFIX_BIT)+#define ETH_MVHDR_DAPREFIX_SPID_PRI         (0x3 << ETH_MVHDR_DAPREFIX_BIT)++#define ETH_MVHDR_MHMASK_BIT                8+#define ETH_MVHDR_MHMASK_MASK               (0x3 << ETH_MVHDR_MHMASK_BIT)+#define ETH_MVHDR_MHMASK_8_QUEUE            (0x0 << ETH_MVHDR_MHMASK_BIT)+#define ETH_MVHDR_MHMASK_4_QUEUE            (0x1 << ETH_MVHDR_MHMASK_BIT)+#define ETH_MVHDR_MHMASK_2_QUEUE            (0x3 << ETH_MVHDR_MHMASK_BIT)+++/* Relevant for 6183 ONLY */+#define ETH_UNIT_PORTS_PADS_CALIB_0_REG     (MV_ETH_REG_BASE(0) + 0x0A0)+#define ETH_UNIT_PORTS_PADS_CALIB_1_REG     (MV_ETH_REG_BASE(0) + 0x0A4)+#define ETH_UNIT_PORTS_PADS_CALIB_2_REG     (MV_ETH_REG_BASE(0) + 0x0A8)+/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG)  */+#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS		0+#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK		(0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)++#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS         5                      +#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK         (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)+ +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS       16                      +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK       (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS) ++#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS        17                   +#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK        (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS) ++#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS        24                   +#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK        (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS) ++#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS        31                   +#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK        (0x1  << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS) +++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvEthRegsh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h	2010-11-09 20:28:11.222495438 +0100@@ -0,0 +1,356 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/*******************************************************************************+* mvEth.h - Header File for : Ethernet Controller +*+* DESCRIPTION:+*       This header file contains macros typedefs and function declaration for+*       Marvell Gigabit Ethernet Controllers.+*+* DEPENDENCIES:+*       None.+*+*******************************************************************************/++#ifndef __mvEth_h__+#define __mvEth_h__++/* includes */+#include "mvTypes.h"+#include "mv802_3.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"+#include "eth/gbe/mvEthRegs.h"+#include "mvSysHwConfig.h"++/* defines  */++#define MV_ETH_EXTRA_FRAGS_NUM      2+++typedef enum+{+    MV_ETH_SPEED_AN,+    MV_ETH_SPEED_10,+    MV_ETH_SPEED_100,+    MV_ETH_SPEED_1000+    +} MV_ETH_PORT_SPEED;++typedef enum+{+    MV_ETH_DUPLEX_AN,+    MV_ETH_DUPLEX_HALF,+    MV_ETH_DUPLEX_FULL+    +} MV_ETH_PORT_DUPLEX;++typedef enum+{+    MV_ETH_FC_AN_ADV_DIS,+    MV_ETH_FC_AN_ADV_SYM,+    MV_ETH_FC_DISABLE,+    MV_ETH_FC_ENABLE++} MV_ETH_PORT_FC;++typedef enum+{+    MV_ETH_PRIO_FIXED = 0,  /* Fixed priority mode */+    MV_ETH_PRIO_WRR   = 1   /* Weighted round robin priority mode */    +} MV_ETH_PRIO_MODE;++/* Ethernet port specific infomation */+typedef struct+{+    int     maxRxPktSize;+    int     rxDefQ;+    int     rxBpduQ;+    int     rxArpQ;+    int     rxTcpQ;+    int     rxUdpQ;+    int     ejpMode;+} MV_ETH_PORT_CFG;++typedef struct+{+    int     descrNum;+} MV_ETH_RX_Q_CFG;++typedef struct+{+    int         descrNum;+    MV_ETH_PRIO_MODE    prioMode;+    int         quota;+} MV_ETH_TX_Q_CFG;++typedef struct+{+    int     maxRxPktSize;+    int     rxDefQ;+    int     txDescrNum[MV_ETH_TX_Q_NUM];+    int     rxDescrNum[MV_ETH_RX_Q_NUM];+    void    *osHandle;+} MV_ETH_PORT_INIT;++typedef struct+{+    MV_BOOL             isLinkUp;+    MV_ETH_PORT_SPEED   speed;+    MV_ETH_PORT_DUPLEX  duplex;+    MV_ETH_PORT_FC      flowControl;++} MV_ETH_PORT_STATUS;++typedef enum+{+	MV_ETH_DISABLE_HEADER_MODE = 0, +	MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1, +	MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2, +	MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3+} MV_ETH_HEADER_MODE;+++/* ethernet.h API list */+void        mvEthHalInit(void);+void        mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);++/* Port Initalization routines */+void*       mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);+void        ethResetTxDescRing(void* pPortHndl, int queue);+void        ethResetRxDescRing(void* pPortHndl, int queue);++void*       mvEthPortHndlGet(int port);++void        mvEthPortFinish(void* pEthPortHndl);+MV_STATUS   mvEthPortDown(void* pEthPortHndl);+MV_STATUS   mvEthPortDisable(void* pEthPortHndl);+MV_STATUS   mvEthPortUp(void* pEthPortHndl);+MV_STATUS   mvEthPortEnable(void* pEthPortHndl);++/* Port data flow routines */+MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);+MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);++/* Port Configuration routines */+MV_STATUS   mvEthDefaultsSet(void* pEthPortHndl);+MV_STATUS   mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);++/* Port RX MAC Filtering control routines */+MV_U8       mvEthMcastCrc8Get(MV_U8* pAddr);+MV_STATUS   mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);+MV_STATUS   mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);+MV_STATUS   mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);++/* MIB Counters APIs */+MV_U32      mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset, +                               MV_U32* pHigh32);+void        mvEthMibCountersClear(void* pPortHandle);++/* TX Scheduling configuration routines */+MV_STATUS   mvEthTxQueueConfig(void* pPortHandle, int txQueue,                          +                               MV_ETH_PRIO_MODE txPrioMode, int txQuota);++/* RX Dispatching configuration routines */+MV_STATUS   mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);+MV_STATUS   mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);+MV_STATUS   mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);+int         mvEthTosToRxqGet(void* pPortHandle, int tos);++/* Speed, Duplex, FlowControl routines */+MV_STATUS   mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed, +                                                   MV_ETH_PORT_DUPLEX duplex);++MV_STATUS   mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);++#if (MV_ETH_VERSION >= 4)+MV_STATUS   mvEthEjpModeSet(void* pPortHandle, int mode);+#endif /* (MV_ETH_VERSION >= 4) */++void        mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);++/* Marvell Header control               */+MV_STATUS   mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);++/* PHY routines */+void       mvEthPhyAddrSet(void* pPortHandle, int phyAddr);+int        mvEthPhyAddrGet(void* pPortHandle);++/* Power management routines */+void        mvEthPortPowerDown(int port);+void        mvEthPortPowerUp(int port);++/******************** ETH PRIVATE ************************/++/*#define UNCACHED_TX_BUFFERS*/+/*#define UNCACHED_RX_BUFFERS*/+++/* Port attributes */+/* Size of a Tx/Rx descriptor used in chain list data structure */+#define ETH_RX_DESC_ALIGNED_SIZE        32+#define ETH_TX_DESC_ALIGNED_SIZE        32++#define TX_DISABLE_TIMEOUT_MSEC     1000+#define RX_DISABLE_TIMEOUT_MSEC     1000+#define TX_FIFO_EMPTY_TIMEOUT_MSEC  10000+#define PORT_DISABLE_WAIT_TCLOCKS   5000++/* Macros that save access to desc in order to find next desc pointer  */+#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl)                              \+        ((pRxDescr) == (pQueueCtrl)->pLastDescr) ?                          \+               (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) :                  \+               (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)++#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl)                              \+        ((pTxDescr) == (pQueueCtrl)->pLastDescr) ?                          \+               (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) :                  \+               (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)++#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl)                              \+        ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ?                          \+               (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) :                  \+               (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)++#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl)                              \+        ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ?                          \+               (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) :                  \+               (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)+++/* Queue specific information */+typedef struct +{+    void*       pFirstDescr;+    void*       pLastDescr;+    void*       pCurrentDescr;+    void*       pUsedDescr;+    int         resource;+    MV_BUF_INFO descBuf;+} ETH_QUEUE_CTRL;+++/* Ethernet port specific infomation */+typedef struct _ethPortCtrl+{+    int             portNo;+    ETH_QUEUE_CTRL  rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource  */+    ETH_QUEUE_CTRL  txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource  */++    MV_ETH_PORT_CFG portConfig;+    MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];+    MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];++    /* Register images - For DP */+    MV_U32          portTxQueueCmdReg;   /* Port active Tx queues summary    */+    MV_U32          portRxQueueCmdReg;   /* Port active Rx queues summary    */++    MV_STATE        portState;++    MV_U8           mcastCount[256];+    MV_U32*         hashPtr;+    void 	    *osHandle;+} ETH_PORT_CTRL; ++/************** MACROs ****************/++/* MACROs to Flush / Invalidate TX / RX Buffers */+#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)+#   define ETH_PACKET_CACHE_FLUSH(pAddr, size)                                  \+        mvOsCacheClear(NULL, (pAddr), (size));                                  \+        /*CPU_PIPE_FLUSH;*/+#else+#   define ETH_PACKET_CACHE_FLUSH(pAddr, size)                                  \+        mvOsIoVirtToPhy(NULL, (pAddr));+#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */++#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )+#   define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)                             \+        mvOsCacheInvalidate (NULL, (pAddr), (size));                            \+        /*CPU_PIPE_FLUSH;*/+#else+#   define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)    +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */++#ifdef ETH_DESCR_UNCACHED++#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)+#define ETH_DESCR_INV(pPortCtrl, pDescr)++#else++#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)      \+        mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))++#define ETH_DESCR_INV(pPortCtrl, pDescr)            \+        mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))++#endif /* ETH_DESCR_UNCACHED */++#include "eth/gbe/mvEthGbe.h"++#endif /* __mvEth_h__ */++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c	2010-11-09 20:28:11.262495582 +0100@@ -0,0 +1,362 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "gpp/mvGpp.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+/* defines  */       +#ifdef MV_DEBUG         +	#define DB(x)	x+#else                +	#define DB(x)    +#endif	             ++static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);++/*******************************************************************************+* mvGppTypeSet - Enable a GPP (OUT) pin+*+* DESCRIPTION:+*+* INPUT:+*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the type+*               of corresponding GPP will be set. Other GPPs are ignored.+*       value - 32bit value that describes GPP type per pin.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Set GPP8 to input and GPP15 to output.+*       mvGppTypeSet(0, (GPP8 | GPP15), +*                    ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)+{+	if (group >= MV_GPP_MAX_GROUP)+	{+		DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));+		return MV_BAD_PARAM;+	}++	gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);++    /* Workaround for Erratum FE-MISC-70*/+    if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))+    {+        mask &= 0x2;+        gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);+    } /*End of WA*/++	return MV_OK;++}++/*******************************************************************************+* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms+*+* DESCRIPTION:+*+* INPUT:+*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the type+*               of corresponding GPP will be set. Other GPPs are ignored.+*       value - 32bit value that describes GPP blink per pin.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Set GPP8 to be static and GPP15 to be blinking.+*       mvGppBlinkEn(0, (GPP8 | GPP15), +*                    ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)+{+	if (group >= MV_GPP_MAX_GROUP)+	{+		DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));+		return MV_BAD_PARAM;+	}++	gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);++	return MV_OK;++}+/*******************************************************************************+* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode+*+* DESCRIPTION:+*+* INPUT:+*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the type+*               of corresponding GPP will be set. Other GPPs are ignored.+*       value - 32bit value that describes GPP polarity per pin.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Set GPP8 to the actual pin value and GPP15 to be inverted.+*       mvGppPolaritySet(0, (GPP8 | GPP15), +*                    ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)+{+	if (group >= MV_GPP_MAX_GROUP)+	{+		DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));+		return MV_BAD_PARAM;+	}++	gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);++	return MV_OK;++}++/*******************************************************************************+* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.+*+* DESCRIPTION:+*+* INPUT:+*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the +*               returned value is valid for it.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Get GPP8 and GPP15 value.+*       mvGppPolarityGet(0, (GPP8 | GPP15));+*+* RETURN:+*       32bit value that describes GPP polatity mode per pin.+*+*******************************************************************************/+MV_U32  mvGppPolarityGet(MV_U32 group, MV_U32 mask)+{+    MV_U32  regVal;++  	if (group >= MV_GPP_MAX_GROUP)+	{+		DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));+		return MV_ERROR;+	}+    regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));+    +    return (regVal & mask);+}++/*******************************************************************************+* mvGppValueGet - Get a GPP Pin list value.+*+* DESCRIPTION:+*       This function get GPP value.+*+* INPUT:+*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the +*               returned value is valid for it.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Get GPP8 and GPP15 value.+*       mvGppValueGet(0, (GPP8 | GPP15));+*+* RETURN:+*       32bit value that describes GPP activity mode per pin.+*+*******************************************************************************/+MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)+{+	MV_U32 gppData;++	gppData = MV_REG_READ(GPP_DATA_IN_REG(group));++	gppData &= mask;++	return gppData;++}++/*******************************************************************************+* mvGppValueSet - Set a GPP Pin list value.+*+* DESCRIPTION:+*       This function set value for given GPP pin list.+*+* INPUT:+*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the +*               value of corresponding GPP will be set accordingly. Other GPP +*               are not affected.+*       value - 32bit value that describes GPP value per pin.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Set GPP8 value of '0' and GPP15 value of '1'.+*       mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)+{+	MV_U32 outEnable, tmp;+	MV_U32 i;++	if (group >= MV_GPP_MAX_GROUP)+	{+		DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));+		return MV_BAD_PARAM;+	}++	/* verify that the gpp pin is configured as output 		*/+	/* Note that in the register out enabled -> bit = '0'. 	*/+	outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));++    /* Workaround for Erratum FE-MISC-70*/+    if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))+    {+        tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));+        outEnable &= 0xfffffffd;+        outEnable |= (tmp & 0x2);+    } /*End of WA*/++	for (i = 0 ; i < 32 ;i++)+	{+		if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))+		{+			mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\+					   "value to GPP %d in input mode.\n", i);+			return MV_ERROR;+		}+	}++	gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);++	return MV_OK;++}+/*******************************************************************************+* gppRegSet - Set a specific GPP pin on a specific GPP register+*+* DESCRIPTION:+*       This function set a specific GPP pin on a specific GPP register+*+* INPUT:+*		regOffs - GPP Register offset +*       group - GPP group number+*       mask  - 32bit mask value. Each set bit in the mask means that the +*               value of corresponding GPP will be set accordingly. Other GPP +*               are not affected.+*       value - 32bit value that describes GPP value per pin.+*+* OUTPUT:+*       None.+*+* EXAMPLE:+*       Set GPP8 value of '0' and GPP15 value of '1'.+*       mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );+*+* RETURN:+*       None.+*+*******************************************************************************/+static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)+{+	MV_U32 gppData;++	gppData = MV_REG_READ(regOffs);++	gppData &= ~mask;++	gppData |= (value & mask);++	MV_REG_WRITE(regOffs, gppData);+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h	2010-11-09 20:28:11.302495429 +0100@@ -0,0 +1,118 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvGppH+#define __INCmvGppH++#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "gpp/mvGppRegs.h"++/* These macros describes the GPP type. Each of the GPPs pins can        	*/+/* be assigned to act as a general purpose input or output pin.             */+#define	MV_GPP_IN	0xFFFFFFFF      			/* GPP input   */+#define MV_GPP_OUT  0    						/* GPP output  */+++/* These macros describes the GPP Out Enable. */+#define	MV_GPP_OUT_DIS	0xFFFFFFFF         	/* Out pin disabled*/+#define MV_GPP_OUT_EN   0    			 	/* Out pin enabled*/++/* These macros describes the GPP Out Blinking. */+/* When set and the corresponding bit in GPIO Data Out Enable Control 		*/+/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of		*/+/* 2^24 TCLK clocks).														*/+#define	MV_GPP_OUT_BLINK	0xFFFFFFFF         	/* Out pin blinking*/+#define MV_GPP_OUT_STATIC   0    			 	/* Out pin static*/+++/* These macros describes the GPP Polarity. */+/* When set to 1 GPIO Data In Register reflects the inverted value of the	*/+/* corresponding pin.														*/++#define	MV_GPP_IN_INVERT	0xFFFFFFFF         	/* Inverted value is got*/+#define MV_GPP_IN_ORIGIN    0    			 	/* original value is got*/++/* mvGppTypeSet - Set PP pin mode (IN or OUT) */+MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);++/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */+MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);++/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */+MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);++/* mvGppPolarityGet - Get the Polarity of a GPP Pin */+MV_U32  mvGppPolarityGet(MV_U32 group, MV_U32 mask);++/* mvGppValueGet - Get a GPP Pin list value.*/+MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);+++/* mvGppValueSet - Set a GPP Pin list value. */+MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);++#endif /* #ifndef __INCmvGppH */ +diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h	2010-11-09 20:28:11.342495467 +0100@@ -0,0 +1,116 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvGppRegsH+#define __INCmvGppRegsH++#define    MV_GPP0  BIT0+#define    MV_GPP1  BIT1+#define    MV_GPP2  BIT2+#define    MV_GPP3  BIT3+#define    MV_GPP4  BIT4+#define    MV_GPP5  BIT5+#define    MV_GPP6  BIT6+#define    MV_GPP7  BIT7+#define    MV_GPP8  BIT8+#define    MV_GPP9  BIT9+#define    MV_GPP10 BIT10+#define    MV_GPP11 BIT11+#define    MV_GPP12 BIT12+#define    MV_GPP13 BIT13+#define    MV_GPP14 BIT14+#define    MV_GPP15 BIT15+#define    MV_GPP16 BIT16+#define    MV_GPP17 BIT17+#define    MV_GPP18 BIT18+#define    MV_GPP19 BIT19+#define    MV_GPP20 BIT20+#define    MV_GPP21 BIT21+#define    MV_GPP22 BIT22+#define    MV_GPP23 BIT23+#define    MV_GPP24 BIT24+#define    MV_GPP25 BIT25+#define    MV_GPP26 BIT26+#define    MV_GPP27 BIT27+#define    MV_GPP28 BIT28+#define    MV_GPP29 BIT29+#define    MV_GPP30 BIT30+#define    MV_GPP31 BIT31+++/* registers offsets */+   +#define GPP_DATA_OUT_REG(grp)			((grp == 0) ? 0x10100 : 0x10140)+#define GPP_DATA_OUT_EN_REG(grp)		((grp == 0) ? 0x10104 : 0x10144)+#define GPP_BLINK_EN_REG(grp)			((grp == 0) ? 0x10108 : 0x10148)+#define GPP_DATA_IN_POL_REG(grp)		((grp == 0) ? 0x1010C : 0x1014c)+#define GPP_DATA_IN_REG(grp)			((grp == 0) ? 0x10110 : 0x10150)+#define GPP_INT_CAUSE_REG(grp)			((grp == 0) ? 0x10114 : 0x10154)+#define GPP_INT_MASK_REG(grp)			((grp == 0) ? 0x10118 : 0x10158)+#define GPP_INT_LVL_REG(grp)			((grp == 0) ? 0x1011c : 0x1015c)++#define GPP_DATA_OUT_SET_REG			0x10120+#define GPP_DATA_OUT_CLEAR_REG			0x10124++#endif /* #ifndef __INCmvGppRegsH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c	2010-11-09 20:28:11.372495482 +0100@@ -0,0 +1,1047 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#include "pci/mvPci.h"++#include "ctrlEnv/mvCtrlEnvLib.h"++/* defines  */       +#ifdef MV_DEBUG         +	#define DB(x)	x+#else                +	#define DB(x)    +#endif	             +					 +++MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)+{+        if (MV_PCI_MOD_HOST == pciIfmod)+    {++                mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));+                mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));+        +                /* Local device master Enable */+                mvPciMasterEnable(pciIf, MV_TRUE);+        +                /* Local device slave Enable */+                mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),+                                                 mvPciLocalDevNumGet(pciIf), MV_TRUE);+        }+        /* enable CPU-2-PCI ordering */+        MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);+}++/*******************************************************************************+* mvPciCommandSet - Set PCI comman register value.+*+* DESCRIPTION:+*       This function sets a given PCI interface with its command register +*       value.+*+* INPUT:+*       pciIf   - PCI interface number.+*       command - 32bit value to be written to comamnd register.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM if pciIf is not in range otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)+{+    MV_U32 locBusNum, locDevNum, regVal;++    locBusNum =  mvPciLocalBusNumGet(pciIf);+    locDevNum =  mvPciLocalDevNumGet(pciIf);++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);+		return MV_BAD_PARAM;+	}++	/* Set command register */+	MV_REG_WRITE(PCI_CMD_REG(pciIf), command);++    /* Upodate device max outstanding split tarnsaction */+    if ((command & PCR_CPU_TO_PCI_ORDER_EN) && +        (command & PCR_PCI_TO_CPU_ORDER_EN))+    {+        /* Read PCI-X command register */+        regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);+                        +        /* clear bits 22:20 */+        regVal &= 0xff8fffff;++        /* set reset value */+        regVal |= (0x3 << 20);+        +        /* Write back the value */+        mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);+    }++	return MV_OK;+++}+++/*******************************************************************************+* mvPciModeGet - Get PCI interface mode.+*+* DESCRIPTION:+*       This function returns the given PCI interface mode.+*+* INPUT:+*       pciIf   - PCI interface number.+*+* OUTPUT:+*       pPciMode - Pointer to PCI mode structure.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)+{+	MV_U32 pciMode;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);+		return MV_BAD_PARAM;+	}+	if (NULL == pPciMode)+	{+		mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL  \n");+		return MV_BAD_PARAM;+	}++	/* Read pci mode register */+	pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));+	+	switch (pciMode & PMR_PCI_MODE_MASK)+	{+		case PMR_PCI_MODE_CONV:+            pPciMode->pciType  = MV_PCI_CONV;++			if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)+			{+				pPciMode->pciSpeed = 66000000; /* 66MHZ */+			}+			else+			{+				pPciMode->pciSpeed = 33000000; /* 33MHZ */+			}+			+			break;+		+		case PMR_PCI_MODE_PCIX_66MHZ:	+			pPciMode->pciType  = MV_PCIX;+			pPciMode->pciSpeed = 66000000; /* 66MHZ */	+			break;+		+		case PMR_PCI_MODE_PCIX_100MHZ:	+			pPciMode->pciType  = MV_PCIX;+			pPciMode->pciSpeed = 100000000; /* 100MHZ */	+			break;+		+		case PMR_PCI_MODE_PCIX_133MHZ:	+			pPciMode->pciType  = MV_PCIX;+			pPciMode->pciSpeed = 133000000; /* 133MHZ */	+			break;++		default:+			{+				mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");+				return MV_ERROR;+			}+	}++	switch (pciMode & PMR_PCI_64_MASK)+	{+		case PMR_PCI_64_64BIT:+			pPciMode->pciWidth = MV_PCI_64;+			break;+		+		case PMR_PCI_64_32BIT:+            pPciMode->pciWidth = MV_PCI_32;+            break;+		+		default:+			{+				mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");+				return MV_ERROR;+			}+	}+	+	return MV_OK;+}++/*******************************************************************************+* mvPciRetrySet - Set PCI retry counters+*+* DESCRIPTION:+*       This function specifies the number of times the PCI controller +*       retries a transaction before it quits.+*       Applies to the PCI Master when acting as a requester.+*       Applies to the PCI slave when acting as a completer (PCI-X mode).+*       A 0x00 value means a "retry forever".+*+* INPUT:+*       pciIf   - PCI interface number.+*       counter - Number of times PCI controller retry. Use counter value +*                 up to PRR_RETRY_CNTR_MAX.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)+{+	MV_U32 pciRetry;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);+		return MV_BAD_PARAM;+	}++	if (counter >= PRR_RETRY_CNTR_MAX)+	{+		mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);+		return MV_BAD_PARAM;++	}++	/* Reading PCI retry register */+    pciRetry  = MV_REG_READ(PCI_RETRY_REG(pciIf));++	pciRetry &= ~PRR_RETRY_CNTR_MASK;++	pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);++	/* write new value */+	MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);++	return MV_OK;+}+++/*******************************************************************************+* mvPciDiscardTimerSet - Set PCI discard timer+*+* DESCRIPTION:+*       This function set PCI discard timer.+*       In conventional PCI mode:+*       Specifies the number of PCLK cycles the PCI slave keeps a non-accessed+*       read buffers (non-completed delayed read) before invalidate the buffer.+*       Set to '0' to disable the timer. The PCI slave waits for delayed +*       read completion forever.+*       In PCI-X mode:+*       Specifies the number of PCLK cycles the PCI master waits for split+*       completion transaction, before it invalidates the pre-allocated read+*       buffer.+*       Set to '0' to disable the timer. The PCI master waits for split +*       completion forever.+*       NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK, +*       unless using the "wait for ever" setting 0x0.+*       NOTE: Must not be updated while there are pending read requests.+*+* INPUT:+*       pciIf      - PCI interface number.+*       pClkCycles - Number of PCI clock cycles.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)+{+	MV_U32 pciDiscardTimer;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n", +																		pciIf);+		return MV_BAD_PARAM;+	}++	if (pClkCycles >= PDTR_TIMER_MIN)+	{+		mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n", 	+																   pClkCycles);+		return MV_BAD_PARAM;++	}++	/* Read  PCI Discard Timer */+	pciDiscardTimer  = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));++	pciDiscardTimer &= ~PDTR_TIMER_MASK;++    pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);++	/* Write new value */+	MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);++	return MV_OK;++}++/* PCI Arbiter routines */++/*******************************************************************************+* mvPciArbEnable - PCI arbiter enable/disable+*+* DESCRIPTION:+*       This fuction enable/disables a given PCI interface arbiter.+*       NOTE: Arbiter setting can not be changed while in work. It should only +*             be set once.+* INPUT:+*       pciIf  - PCI interface number.+*       enable - Enable/disable parameter. If enable = MV_TRUE then enable.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)+{+	MV_U32 regVal;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);+		return MV_ERROR;+	}+    	+    /* Set PCI Arbiter Control register according to default configuration 	*/+	regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));++	/* Make sure arbiter disabled before changing its values */+	MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE); ++	regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;	++	regVal |= PCI_ARBITER_CTRL_DEFAULT;		/* Set default configuration	*/++	if (MV_TRUE == enable)+	{+		regVal |= PACR_ARB_ENABLE; +	}+	else+	{+		regVal &= ~PACR_ARB_ENABLE; +	}++	/* Write to register 										            */+	MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);++	return MV_OK;	+}+++/*******************************************************************************+* mvPciArbParkDis - Disable arbiter parking on agent+*+* DESCRIPTION:+*       This function disables the PCI arbiter from parking on the given agent+*       list.+*+* INPUT:+*       pciIf        - PCI interface number.+*       pciAgentMask - When a bit in the mask is set to '1', parking on +*                      the associated PCI master is disabled. Mask bit +*                      refers to bit 0 - 6. For example disable parking on PCI+*                      agent 3 set pciAgentMask 0x4 (bit 3 is set).+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)+{+	MV_U32 pciArbiterCtrl;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);+		return MV_ERROR;+	}++	/* Reading Arbiter Control register */+	pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));++	/* Arbiter must be disabled before changing parking */+	MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE); ++	/* do the change */+    pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;+	pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);++	/* writing new value ( if th earbiter was enabled before the change		*/ +	/* here it will be reenabled 											*/+	MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);++	return MV_OK;+}+++/*******************************************************************************+* mvPciArbBrokDetectSet - Set PCI arbiter broken detection+*+* DESCRIPTION:+*       This function sets the maximum number of cycles that the arbiter +*       waits for a PCI master to respond to its grant assertion. If a +*       PCI agent fails to respond within this time, the PCI arbiter aborts +*       the transaction and performs a new arbitration cycle.+*       NOTE: Value must be greater than '1' for conventional PCI and +*       greater than '5' for PCI-X.+*+* INPUT:+*       pciIf      - PCI interface number.+*       pClkCycles - Number of PCI clock cycles. If equal to '0' the broken+*                    master detection is disabled.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)+{+	MV_U32 pciArbiterCtrl;+	MV_U32 pciMode;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n", +																		pciIf);+		return MV_BAD_PARAM;+	}++	/* Checking PCI mode and if pClkCycles is legal value */+	pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));+	pciMode &= PMR_PCI_MODE_MASK;++	if (PMR_PCI_MODE_CONV == pciMode)+	{+		if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN) +			return MV_ERROR;+	}+	else+	{+		if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN) +			return MV_ERROR;+	}++	pClkCycles <<= PACR_BROKEN_VAL_OFFS;++	/* Reading Arbiter Control register */+	pciArbiterCtrl  = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));+	pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;+	pciArbiterCtrl |= pClkCycles;++	/* Arbiter must be disabled before changing broken detection */+	MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE); ++	/* writing new value ( if th earbiter was enabled before the change 	*/+	/* here it will be reenabled 											*/++	MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);++	return MV_OK;+}++/* PCI configuration space read write */++/*******************************************************************************+* mvPciConfigRead - Read from configuration space+*+* DESCRIPTION:+*       This function performs a 32 bit read from PCI configuration space.+*       It supports both type 0 and type 1 of Configuration Transactions +*       (local and over bridge). In order to read from local bus segment, use +*       bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers +*       will result configuration transaction of type 1 (over bridge).+*+* INPUT:+*       pciIf   - PCI interface number.+*       bus     - PCI segment bus number.+*       dev     - PCI device number.+*       func    - Function number.+*       regOffs - Register offset.       +*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit register data, 0xffffffff on error+*+*******************************************************************************/+MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func, +                        MV_U32 regOff)+{+	MV_U32 pciData = 0;++	/* Parameter checking   */+	if (PCI_DEFAULT_IF != pciIf)+	{+		if (pciIf >= mvCtrlPciMaxIfGet())+		{+			mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);+			return 0xFFFFFFFF;+		}+	}++	if (dev >= MAX_PCI_DEVICES)+	{+		DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));+		return 0xFFFFFFFF;+	}+	+	if (func >= MAX_PCI_FUNCS)+	{+		DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));+		return 0xFFFFFFFF;+	}+	+	if (bus >= MAX_PCI_BUSSES)+	{+		DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));+		return MV_ERROR;+	}+++	/* Creating PCI address to be passed */+	pciData |= (bus << PCAR_BUS_NUM_OFFS);+	pciData |= (dev << PCAR_DEVICE_NUM_OFFS);+	pciData |= (func << PCAR_FUNC_NUM_OFFS);+	pciData |= (regOff & PCAR_REG_NUM_MASK);++	pciData |= PCAR_CONFIG_EN; +	+	/* Write the address to the PCI configuration address register */+	MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);++	/* In order to let the PCI controller absorbed the address of the read 	*/+	/* transaction we perform a validity check that the address was written */+	if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))+	{+		return MV_ERROR;+	}+	/* Read the Data returned in the PCI Data register */+	pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));++	return pciData;+}++/*******************************************************************************+* mvPciConfigWrite - Write to configuration space+*+* DESCRIPTION:+*       This function performs a 32 bit write to PCI configuration space.+*       It supports both type 0 and type 1 of Configuration Transactions +*       (local and over bridge). In order to write to local bus segment, use +*       bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers +*       will result configuration transaction of type 1 (over bridge).+*+* INPUT:+*       pciIf   - PCI interface number.+*       bus     - PCI segment bus number.+*       dev     - PCI device number.+*       func    - Function number.+*       regOffs - Register offset.       +*       data    - 32bit data.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, +                           MV_U32 func, MV_U32 regOff, MV_U32 data)+{+	MV_U32 pciData = 0;++	/* Parameter checking   */+	if (PCI_DEFAULT_IF != pciIf)+	{+		if (pciIf >= mvCtrlPciMaxIfGet())+		{+			mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n", +																		pciIf);+			return 0xFFFFFFFF;+		}+	}++	if (dev >= MAX_PCI_DEVICES)+	{+		mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);+		return MV_BAD_PARAM;+	}++	if (func >= MAX_PCI_FUNCS)+	{+		mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);+		return MV_ERROR;+	}++	if (bus >= MAX_PCI_BUSSES)+	{+		mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);+		return MV_ERROR;+	}++	/* Creating PCI address to be passed */+	pciData |= (bus << PCAR_BUS_NUM_OFFS);+	pciData |= (dev << PCAR_DEVICE_NUM_OFFS);+	pciData |= (func << PCAR_FUNC_NUM_OFFS);+	pciData |= (regOff & PCAR_REG_NUM_MASK);++	pciData |= PCAR_CONFIG_EN;+	+	/* Write the address to the PCI configuration address register */+	MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);++	/* In order to let the PCI controller absorbed the address of the read 	*/+	/* transaction we perform a validity check that the address was written */+	if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))+	{+		return MV_ERROR;+	}++	/* Write the Data passed to the PCI Data register */+	MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);++	return MV_OK;+}++/*******************************************************************************+* mvPciMasterEnable - Enable/disale PCI interface master transactions.+*+* DESCRIPTION:+*       This function performs read modified write to PCI command status +*       (offset 0x4) to set/reset bit 2. After this bit is set, the PCI +*       master is allowed to gain ownership on the bus, otherwise it is +*       incapable to do so.+*+* INPUT:+*       pciIf  - PCI interface number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)+{+	MV_U32 pciCommandStatus;+	MV_U32 RegOffs;+	MV_U32 localBus;+	MV_U32 localDev;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);+		return MV_ERROR;+	}++	localBus = mvPciLocalBusNumGet(pciIf);+	localDev = mvPciLocalDevNumGet(pciIf);+	+	RegOffs = PCI_STATUS_AND_COMMAND;++	pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);++	if (MV_TRUE == enable)+	{+		pciCommandStatus |= PSCR_MASTER_EN;+	}+	else+	{+		pciCommandStatus &= ~PSCR_MASTER_EN;+	}++	mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);++	return MV_OK;+}+++/*******************************************************************************+* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.+*+* DESCRIPTION:+*       This function performs read modified write to PCI command status +*       (offset 0x4) to set/reset bit 0 and 1. After those bits are set, +*       the PCI slave is allowed to respond to PCI IO space access (bit 0) +*       and PCI memory space access (bit 1). +*+* INPUT:+*       pciIf  - PCI interface number.+*       dev     - PCI device number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)+{+	MV_U32 pciCommandStatus;+	MV_U32 RegOffs;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);+		return MV_BAD_PARAM;+	}+	if (dev >= MAX_PCI_DEVICES)+	{+		mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);+		return MV_BAD_PARAM;++	}++	RegOffs = PCI_STATUS_AND_COMMAND;+	+	pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);++    if (MV_TRUE == enable)+	{+		pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);+	}+	else                             +	{+		pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);+	}++	mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);++	return MV_OK;+}++/*******************************************************************************+* mvPciLocalBusNumSet - Set PCI interface local bus number.+*+* DESCRIPTION:+*       This function sets given PCI interface its local bus number.+*       Note: In case the PCI interface is PCI-X, the information is read-only.+*+* INPUT:+*       pciIf  - PCI interface number.+*       busNum - Bus number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_NOT_ALLOWED in case PCI interface is PCI-X. +*       MV_BAD_PARAM on bad parameters ,+*       otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)+{+	MV_U32 pciP2PConfig;+	MV_PCI_MODE pciMode;+	MV_U32 localBus;+	MV_U32 localDev;+++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);+		return MV_BAD_PARAM;+	}+	if (busNum >= MAX_PCI_BUSSES)+	{+		mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);+		return MV_ERROR;++	}++	localBus = mvPciLocalBusNumGet(pciIf);+	localDev = mvPciLocalDevNumGet(pciIf);+++	/* PCI interface mode */+	mvPciModeGet(pciIf, &pciMode);++	/* if PCI type is PCI-X then it is not allowed to change the dev number */+	if (MV_PCIX == pciMode.pciType)+	{+		pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );++		pciP2PConfig &= ~PXS_BN_MASK;++		pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;++		mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );++	}+	else+	{+		pciP2PConfig  = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));++		pciP2PConfig &= ~PPCR_BUS_NUM_MASK;++		pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;++		MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);++	}+++	return MV_OK;+}+++/*******************************************************************************+* mvPciLocalBusNumGet - Get PCI interface local bus number.+*+* DESCRIPTION:+*       This function gets the local bus number of a given PCI interface.+*+* INPUT:+*       pciIf  - PCI interface number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Local bus number.0xffffffff on Error+*+*******************************************************************************/+MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)+{+	MV_U32 pciP2PConfig;++	/* Parameter checking   */+	if (PCI_DEFAULT_IF != pciIf)+	{+		if (pciIf >= mvCtrlPciMaxIfGet())+		{+			mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n", +													   					pciIf);+			return 0xFFFFFFFF;+		}+	}++	pciP2PConfig  = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));+	pciP2PConfig &= PPCR_BUS_NUM_MASK;+	return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);+}+++/*******************************************************************************+* mvPciLocalDevNumSet - Set PCI interface local device number.+*+* DESCRIPTION:+*       This function sets given PCI interface its local device number.+*       Note: In case the PCI interface is PCI-X, the information is read-only.+*+* INPUT:+*       pciIf  - PCI interface number.+*       devNum - Device number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,+*       otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)+{+	MV_U32 pciP2PConfig;+	MV_PCI_MODE pciMode;+	MV_U32 localBus;+	MV_U32 localDev;++	/* Parameter checking   */+	if (pciIf >= mvCtrlPciMaxIfGet())+	{+		mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);+		return MV_BAD_PARAM;+	}+	if (devNum >= MAX_PCI_DEVICES)+	{+		mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", +																	   devNum);+		return MV_BAD_PARAM;++	}+	+	localBus = mvPciLocalBusNumGet(pciIf);+	localDev = mvPciLocalDevNumGet(pciIf);++	/* PCI interface mode */+	mvPciModeGet(pciIf, &pciMode);++	/* if PCI type is PCIX then it is not allowed to change the dev number */+	if (MV_PCIX == pciMode.pciType)+	{+		pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );++		pciP2PConfig &= ~PXS_DN_MASK;++		pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;++		mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );+	}+	else+	{+		pciP2PConfig  = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));++		pciP2PConfig &= ~PPCR_DEV_NUM_MASK;++		pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;++		MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);+	}++	return MV_OK;+}++/*******************************************************************************+* mvPciLocalDevNumGet - Get PCI interface local device number.+*+* DESCRIPTION:+*       This function gets the local device number of a given PCI interface.+*+* INPUT:+*       pciIf  - PCI interface number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Local device number. 0xffffffff on Error+*+*******************************************************************************/+MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)+{+	MV_U32 pciP2PConfig;++	/* Parameter checking   */+	+	if (PCI_DEFAULT_IF != pciIf)+	{+		if (pciIf >= mvCtrlPciMaxIfGet())+		{+			mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n", +																   		pciIf);+			return 0xFFFFFFFF;+		}+	}+	+	pciP2PConfig  = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));++	pciP2PConfig &= PPCR_DEV_NUM_MASK;++	return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);+}++++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h	2010-11-09 20:28:11.412495457 +0100@@ -0,0 +1,185 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#ifndef __INCPCIH+#define __INCPCIH++#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"+#include "pci/mvPciRegs.h"+++/* NOTE not supported in this driver:++ Built In Self Test (BIST)+ Vital Product Data (VPD)+ Message Signaled Interrupt (MSI)+ Power Management+ Compact PCI Hot Swap+ Header retarget+ +Registers not supported: +1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)+2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)+*/  ++/* defines */+/* The number of supported PCI interfaces depend on Marvell controller 		*/+/* device number. This device number ID is located on the PCI unit 			*/+/* configuration header. This creates a loop where calling PCI 				*/+/* configuration read/write	routine results a call to get PCI configuration */+/* information etc. This macro defines a default PCI interface. This PCI	*/+/* interface is sure to exist.												*/+#define PCI_DEFAULT_IF	0+++/* typedefs */+/* The Marvell controller supports both conventional PCI and PCI-X.         */+/* This enumeration describes the PCI type.                                 */+typedef enum _mvPciType+{+    MV_PCI_CONV,    /* Conventional PCI */+    MV_PCIX         /* PCI-X            */+}MV_PCI_TYPE;++typedef enum _mvPciMod+{+	MV_PCI_MOD_HOST,+	MV_PCI_MOD_DEVICE+}MV_PCI_MOD;+++/* The Marvell controller supports both PCI width of 32 and 64 bit.         */+/* This enumerator describes PCI width                                      */+typedef enum _mvPciWidth+{+    MV_PCI_32,  /* PCI width 32bit  */+    MV_PCI_64   /* PCI width 64bit  */+}MV_PCI_WIDTH;++/* This structure describes the PCI unit configured type, speed and width.  */+typedef struct _mvPciMode+{+    MV_PCI_TYPE  pciType;    /* PCI type                                    */+    MV_U32       pciSpeed;   /* Assuming PCI base clock on board is 33MHz   */+    MV_PCI_WIDTH pciWidth;   /* PCI bus width                               */+}MV_PCI_MODE;++/* mvPciInit - Initialize PCI interfaces*/+MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);++/* mvPciCommandSet - Set PCI comman register value.*/+MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);++/* mvPciModeGet - Get PCI interface mode.*/+MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);++/* mvPciRetrySet - Set PCI retry counters*/+MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);++/* mvPciDiscardTimerSet - Set PCI discard timer*/+MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);++/* mvPciArbEnable - PCI arbiter enable/disable*/+MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);++/* mvPciArbParkDis - Disable arbiter parking on agent */+MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);++/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */+MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);++/* mvPciConfigRead - Read from configuration space */+MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,+						MV_U32 func,MV_U32 regOff);++/* mvPciConfigWrite - Write to configuration space */+MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,+                           MV_U32 func, MV_U32 regOff, MV_U32 data);++/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/+MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);++/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/+MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);++/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/+MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);++/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/+MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);++/* mvPciLocalDevNumSet - Set PCI interface local device number.*/+MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);++/* mvPciLocalDevNumGet - Get PCI interface local device number.*/+MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);+++#endif /* #ifndef __INCPCIH */+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h	2010-11-09 20:28:11.452495500 +0100@@ -0,0 +1,411 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCPCIREGSH+#define __INCPCIREGSH+++#include "pci-if/mvPciIfRegs.h"+/* defines */+#define MAX_PCI_DEVICES         32+#define MAX_PCI_FUNCS           8+#define MAX_PCI_BUSSES          128++/* enumerators */++/* This enumerator described the possible PCI slave targets.    	   */+/* PCI slave targets are designated memory/IO address spaces that the  */+/* PCI slave targets can access. They are also refered as "targets"    */+/* this enumeratoe order is determined by the content of : +		PCI_BASE_ADDR_ENABLE_REG 				 					*/+++/* registers offsetes defines */++++/*************************/+/* PCI control registers */+/*************************/+/* maen : should add new registers */+#define PCI_CMD_REG(pciIf)				 		(0x30c00  + ((pciIf) * 0x80))+#define PCI_MODE_REG(pciIf)				 		(0x30d00  + ((pciIf) * 0x80))+#define PCI_RETRY_REG(pciIf)					(0x30c04  + ((pciIf) * 0x80))+#define PCI_DISCARD_TIMER_REG(pciIf)			(0x30d04  + ((pciIf) * 0x80))+#define PCI_ARBITER_CTRL_REG(pciIf)				(0x31d00 + ((pciIf) * 0x80))+#define PCI_P2P_CONFIG_REG(pciIf)				(0x31d14 + ((pciIf) * 0x80))+#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \+							(0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))+#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \+							(0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))+#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin)	\+							(0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))+							+#define PCI_DLL_CTRL_REG(pciIf)	   		 		(0x31d20  + ((pciIf) * 0x80))++/* PCI Dll Control (PDC)*/+#define PDC_DLL_EN					BIT0+++/* PCI Command Register (PCR) */+#define PCR_MASTER_BYTE_SWAP_EN     BIT0+#define PCR_MASTER_WR_COMBINE_EN    BIT4+#define PCR_MASTER_RD_COMBINE_EN    BIT5+#define PCR_MASTER_WR_TRIG_WHOLE    BIT6+#define PCR_MASTER_RD_TRIG_WHOLE    BIT7+#define PCR_MASTER_MEM_RD_LINE_EN   BIT8+#define PCR_MASTER_MEM_RD_MULT_EN   BIT9+#define PCR_MASTER_WORD_SWAP_EN     BIT10+#define PCR_SLAVE_WORD_SWAP_EN      BIT11+#define PCR_NS_ACCORDING_RCV_TRANS  BIT14+#define PCR_MASTER_PCIX_REQ64N_EN   BIT15+#define PCR_SLAVE_BYTE_SWAP_EN      BIT16+#define PCR_MASTER_DAC_EN           BIT17+#define PCR_MASTER_M64_ALLIGN       BIT18+#define PCR_ERRORS_PROPAGATION_EN   BIT19+#define PCR_SLAVE_SWAP_ENABLE       BIT20+#define PCR_MASTER_SWAP_ENABLE      BIT21+#define PCR_MASTER_INT_SWAP_EN      BIT22+#define PCR_LOOP_BACK_ENABLE        BIT23+#define PCR_SLAVE_INTREG_SWAP_OFFS  24+#define PCR_SLAVE_INTREG_SWAP_MASK  0x3+#define PCR_SLAVE_INTREG_BYTE_SWAP  \+                             (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)+#define PCR_SLAVE_INTREG_NO_SWAP    \+                             (MV_NO_SWAP   << PCR_SLAVE_INT_REG_SWAP_MASK)+#define PCR_SLAVE_INTREG_BYTE_WORD  \+                             (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)+#define PCR_SLAVE_INTREG_WORD_SWAP  \+                             (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)+#define PCR_RESET_REASSERTION_EN    BIT26+#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28+#define PCR_CPU_TO_PCI_ORDER_EN     BIT29+#define PCR_PCI_TO_CPU_ORDER_EN     BIT30++/* PCI Mode Register (PMR) */+#define PMR_PCI_ID_OFFS 			0  /* PCI Interface ID */+#define PMR_PCI_ID_MASK 			(0x1 << PMR_PCI_ID_OFFS)+#define PMR_PCI_ID_PCI(pciNum) 		((pciNum) << PCI_MODE_PCIID_OFFS)++#define PMR_PCI_64_OFFS				2 	/* 64-bit PCI Interface */+#define PMR_PCI_64_MASK				(0x1 << PMR_PCI_64_OFFS)+#define PMR_PCI_64_64BIT			(0x1 << PMR_PCI_64_OFFS)+#define PMR_PCI_64_32BIT			(0x0 << PMR_PCI_64_OFFS)++#define PMR_PCI_MODE_OFFS			4 	/* PCI interface mode of operation */+#define PMR_PCI_MODE_MASK			(0x3 << PMR_PCI_MODE_OFFS)+#define PMR_PCI_MODE_CONV			(0x0 << PMR_PCI_MODE_OFFS)+#define PMR_PCI_MODE_PCIX_66MHZ		(0x1 << PMR_PCI_MODE_OFFS)+#define PMR_PCI_MODE_PCIX_100MHZ	(0x2 << PMR_PCI_MODE_OFFS)+#define PMR_PCI_MODE_PCIX_133MHZ	(0x3 << PMR_PCI_MODE_OFFS)++#define PMR_EXP_ROM_SUPPORT			BIT8	/* Expansion ROM Active */++#define PMR_PCI_RESET_OFFS			31 /* PCI Interface Reset Indication */+#define PMR_PCI_RESET_MASK			(0x1 << PMR_PCI_RESET_OFFS)+#define PMR_PCI_RESET_PCIXRST		(0x0 << PMR_PCI_RESET_OFFS)+++/* PCI Retry Register (PRR) */+#define PRR_RETRY_CNTR_OFFS			16 /* Retry Counter */+#define PRR_RETRY_CNTR_MAX			0xff+#define PRR_RETRY_CNTR_MASK			(PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)+++/* PCI Discard Timer Register (PDTR) */+#define PDTR_TIMER_OFFS				0	/* Timer */+#define PDTR_TIMER_MAX				0xffff+#define PDTR_TIMER_MIN				0x7F+#define PDTR_TIMER_MASK				(PDTR_TIMER_MAX << PDTR_TIMER_OFFS)+++/* PCI Arbiter Control Register (PACR) */+#define PACR_BROKEN_DETECT_EN		BIT1	/* Broken Detection Enable */++#define PACR_BROKEN_VAL_OFFS		3	/* Broken Value */+#define PACR_BROKEN_VAL_MASK		(0xf << PACR_BROKEN_VAL_OFFS)+#define PACR_BROKEN_VAL_CONV_MIN	0x2+#define PACR_BROKEN_VAL_PCIX_MIN	0x6++#define PACR_PARK_DIS_OFFS		14	/* Parking Disable */+#define PACR_PARK_DIS_MAX_AGENT	0x3f+#define PACR_PARK_DIS_MASK		(PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)+#define PACR_PARK_DIS(agent)	((1 << (agent)) << PACR_PARK_DIS_OFFS)++#define PACR_ARB_ENABLE				BIT31	/* Enable Internal Arbiter */+++/* PCI P2P Configuration Register (PPCR) */+#define PPCR_2ND_BUS_L_OFFS			0	/* 2nd PCI Interface Bus Range Lower */+#define PPCR_2ND_BUS_L_MASK			(0xff << PPCR_2ND_BUS_L_OFFS)++#define PPCR_2ND_BUS_H_OFFS			8	/* 2nd PCI Interface Bus Range Upper */+#define PPCR_2ND_BUS_H_MASK			(0xff << PPCR_2ND_BUS_H_OFFS)++#define PPCR_BUS_NUM_OFFS			16  /* The PCI interface's Bus number */+#define PPCR_BUS_NUM_MASK			(0xff << PPCR_BUS_NUM_OFFS)++#define PPCR_DEV_NUM_OFFS			24  /* The PCI interface’s Device number */+#define PPCR_DEV_NUM_MASK			(0xff << PPCR_DEV_NUM_OFFS)+++/* PCI Access Control Base Low Register (PACBLR) */+#define PACBLR_EN					BIT0 /* Access control window enable */++#define PACBLR_ACCPROT				BIT4 /* Access Protect */+#define PACBLR_WRPROT				BIT5 /* Write Protect */++#define PACBLR_PCISWAP_OFFS			6 	 /* PCI slave Data Swap Control */+#define PACBLR_PCISWAP_MASK			(0x3 << PACBLR_PCISWAP_OFFS)+#define PACBLR_PCISWAP_BYTE			(0x0 << PACBLR_PCISWAP_OFFS)+#define PACBLR_PCISWAP_NO_SWAP		(0x1 << PACBLR_PCISWAP_OFFS)+#define PACBLR_PCISWAP_BYTE_WORD	(0x2 << PACBLR_PCISWAP_OFFS)+#define PACBLR_PCISWAP_WORD			(0x3 << PACBLR_PCISWAP_OFFS)++#define PACBLR_RDMBURST_OFFS		8 /* Read Max Burst */+#define PACBLR_RDMBURST_MASK		(0x3 << PACBLR_RDMBURST_OFFS)+#define PACBLR_RDMBURST_32BYTE		(0x0 << PACBLR_RDMBURST_OFFS)+#define PACBLR_RDMBURST_64BYTE		(0x1 << PACBLR_RDMBURST_OFFS)+#define PACBLR_RDMBURST_128BYTE		(0x2 << PACBLR_RDMBURST_OFFS)++#define PACBLR_RDSIZE_OFFS			10 /* Typical PCI read transaction Size. */+#define PACBLR_RDSIZE_MASK			(0x3 << PACBLR_RDSIZE_OFFS)+#define PACBLR_RDSIZE_32BYTE		(0x0 << PACBLR_RDSIZE_OFFS)+#define PACBLR_RDSIZE_64BYTE		(0x1 << PACBLR_RDSIZE_OFFS)+#define PACBLR_RDSIZE_128BYTE		(0x2 << PACBLR_RDSIZE_OFFS)+#define PACBLR_RDSIZE_256BYTE		(0x3 << PACBLR_RDSIZE_OFFS)++#define PACBLR_BASE_L_OFFS			12	/* Corresponds to address bits [31:12] */+#define PACBLR_BASE_L_MASK			(0xfffff << PACBLR_BASE_L_OFFS)+#define PACBLR_BASE_L_ALIGNMENT		(1 << PACBLR_BASE_L_OFFS)+#define PACBLR_BASE_ALIGN_UP(base)  \+                             ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)+#define PACBLR_BASE_ALIGN_DOWN(base)  (base & PACBLR_BASE_L_MASK)+++/* PCI Access Control Base High Register (PACBHR) 	*/+#define PACBHR_BASE_H_OFFS			0	/* Corresponds to address bits [63:32] */+#define PACBHR_CTRL_BASE_H_MASK		(0xffffffff << PACBHR_BASE_H_OFFS)++/* PCI Access Control Size Register (PACSR) 		*/+#define PACSR_WRMBURST_OFFS			8 /* Write Max Burst */+#define PACSR_WRMBURST_MASK			(0x3 << PACSR_WRMBURST_OFFS)+#define PACSR_WRMBURST_32BYTE		(0x0 << PACSR_WRMBURST_OFFS)+#define PACSR_WRMBURST_64BYTE		(0x1 << PACSR_WRMBURST_OFFS)+#define PACSR_WRMBURST_128BYTE		(0x2 << PACSR_WRMBURST_OFFS)++#define PACSR_PCI_ORDERING			BIT11 /* PCI Ordering required */++#define PACSR_SIZE_OFFS				12	/* PCI access window size */+#define PACSR_SIZE_MASK				(0xfffff << PACSR_SIZE_OFFS)+#define PACSR_SIZE_ALIGNMENT		(1 << PACSR_SIZE_OFFS)+#define PACSR_SIZE_ALIGN_UP(size)   \+                                   ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)+#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)+++/***************************************/+/* PCI Configuration Access Registers  */+/***************************************/++#define PCI_CONFIG_ADDR_REG(pciIf)	(0x30C78 - ((pciIf) * 0x80) )+#define PCI_CONFIG_DATA_REG(pciIf)	(0x30C7C - ((pciIf) * 0x80) )+#define PCI_INT_ACK_REG(pciIf)		(0x30C34 + ((pciIf) * 0x80) )++/* PCI Configuration Address Register (PCAR) */+#define PCAR_REG_NUM_OFFS			2+#define PCAR_REG_NUM_MASK			(0x3F << PCAR_REG_NUM_OFFS)+		+#define PCAR_FUNC_NUM_OFFS			8+#define PCAR_FUNC_NUM_MASK			(0x7 << PCAR_FUNC_NUM_OFFS)+		+#define PCAR_DEVICE_NUM_OFFS		11+#define PCAR_DEVICE_NUM_MASK		(0x1F << PCAR_DEVICE_NUM_OFFS)+		+#define PCAR_BUS_NUM_OFFS			16+#define PCAR_BUS_NUM_MASK			(0xFF << PCAR_BUS_NUM_OFFS)+		+#define PCAR_CONFIG_EN				BIT31+++/***************************************/+/* PCI Configuration registers */+/***************************************/++/*********************************************/+/* PCI Configuration, Function 0, Registers  */+/*********************************************/++/* Marvell Specific */+#define PCI_SCS0_BASE_ADDR_LOW			   			0x010+#define PCI_SCS0_BASE_ADDR_HIGH			   			0x014+#define PCI_SCS1_BASE_ADDR_LOW		  				0x018+#define PCI_SCS1_BASE_ADDR_HIGH			  			0x01C+#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 		0x020+#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H		0x024++/* capability list */+#define PCI_POWER_MNG_CAPABILITY		            0x040+#define PCI_POWER_MNG_STATUS_CONTROL		        0x044+#define PCI_VPD_ADDRESS_REG	                        0x048+#define PCI_VPD_DATA_REG	                        0x04c+#define PCI_MSI_MESSAGE_CONTROL						0x050+#define PCI_MSI_MESSAGE_ADDR		                0x054+#define PCI_MSI_MESSAGE_UPPER_ADDR		            0x058+#define PCI_MSI_MESSAGE_DATA		                0x05c+#define PCIX_COMMAND		                        0x060+#define PCIX_STATUS		                            0x064+#define PCI_COMPACT_PCI_HOT_SWAP		            0x068+++/*********************************************/+/* PCI Configuration, Function 1, Registers  */+/*********************************************/++#define PCI_SCS2_BASE_ADDR_LOW						0x10+#define PCI_SCS2_BASE_ADDR_HIGH						0x14+#define PCI_SCS3_BASE_ADDR_LOW		 				0x18+#define PCI_SCS3_BASE_ADDR_HIGH						0x1c+++/***********************************************/+/*  PCI Configuration, Function 2, Registers   */+/***********************************************/++#define PCI_DEVCS0_BASE_ADDR_LOW					0x10+#define PCI_DEVCS0_BASE_ADDR_HIGH		 			0x14+#define PCI_DEVCS1_BASE_ADDR_LOW		 			0x18+#define PCI_DEVCS1_BASE_ADDR_HIGH		      		0x1c+#define PCI_DEVCS2_BASE_ADDR_LOW		 			0x20+#define PCI_DEVCS2_BASE_ADDR_HIGH		      		0x24++/***********************************************/+/*  PCI Configuration, Function 3, Registers   */+/***********************************************/++#define PCI_BOOTCS_BASE_ADDR_LOW					0x18+#define PCI_BOOTCS_BASE_ADDR_HIGH		      		0x1c++/***********************************************/+/*  PCI Configuration, Function 4, Registers   */+/***********************************************/++#define PCI_P2P_MEM0_BASE_ADDR_LOW				   	0x10+#define PCI_P2P_MEM0_BASE_ADDR_HIGH		 			0x14+#define PCI_P2P_IO_BASE_ADDR		               	0x20+#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR		   0x24++/* PCIX_STATUS  register fields (PXS) */++#define PXS_FN_OFFS		0	/* Description Number */+#define PXS_FN_MASK		(0x7 << PXS_FN_OFFS)++#define PXS_DN_OFFS		3	/* Device Number */+#define PXS_DN_MASK		(0x1f << PXS_DN_OFFS)++#define PXS_BN_OFFS		8	/* Bus Number */+#define PXS_BN_MASK		(0xff << PXS_BN_OFFS)+++/* PCI Error Report Register Map */+#define PCI_SERRN_MASK_REG(pciIf)		(0x30c28  + (pciIf * 0x80))+#define PCI_CAUSE_REG(pciIf)			(0x31d58 + (pciIf * 0x80))+#define PCI_MASK_REG(pciIf)				(0x31d5C + (pciIf * 0x80))+#define PCI_ERROR_ADDR_LOW_REG(pciIf)	(0x31d40 + (pciIf * 0x80))+#define PCI_ERROR_ADDR_HIGH_REG(pciIf)	(0x31d44 + (pciIf * 0x80))+#define PCI_ERROR_ATTRIBUTE_REG(pciIf)	(0x31d48 + (pciIf * 0x80))+#define PCI_ERROR_COMMAND_REG(pciIf)	(0x31d50 + (pciIf * 0x80))++/* PCI Interrupt Cause Register (PICR) */+#define PICR_ERR_SEL_OFFS           27+#define PICR_ERR_SEL_MASK           (0x1f << PICR_ERR_SEL_OFFS)++/* PCI Error Command Register (PECR) */+#define PECR_ERR_CMD_OFFS			0+#define PECR_ERR_CMD_MASK			(0xf << PECR_ERR_CMD_OFFS)+#define PECR_DAC					BIT4+++/* defaults */+/* Set bits means value is about to change according to new value */+#define PCI_COMMAND_DEFAULT_MASK                0xffffdff1+#define PCI_COMMAND_DEFAULT                             \+                (PCR_MASTER_WR_TRIG_WHOLE   |   \+         PCR_MASTER_RD_TRIG_WHOLE       |       \+                 PCR_MASTER_MEM_RD_LINE_EN      |       \+         PCR_MASTER_MEM_RD_MULT_EN  |   \+                 PCR_NS_ACCORDING_RCV_TRANS     |       \+                 PCR_MASTER_PCIX_REQ64N_EN      |       \+                 PCR_MASTER_DAC_EN                      |       \+                 PCR_MASTER_M64_ALLIGN          |       \+                 PCR_ERRORS_PROPAGATION_EN)+                 +                 +#define PCI_ARBITER_CTRL_DEFAULT_MASK   0x801fc07a+#define PCI_ARBITER_CTRL_DEFAULT        \+        (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)+++#endif /* #ifndef __INCPCIREGSH */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c	2010-11-09 20:28:11.512532816 +0100@@ -0,0 +1,669 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvPciIf.h"+#include "ctrlEnv/sys/mvSysPex.h"++#if defined(MV_INCLUDE_PCI)+#include "ctrlEnv/sys/mvSysPci.h"+#endif+++/* defines  */       +#ifdef MV_DEBUG         +	#define DB(x)	x+#else                +	#define DB(x)    +#endif	             +					 ++/*******************************************************************************+* mvPciInit - Initialize PCI interfaces+*+* DESCRIPTION:+*+* INPUT:+*+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM+*+*******************************************************************************/+++MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		+        MV_PCI_MOD pciMod;+		+        if (PCI_IF_MODE_HOST == pciIfmode)+        {+            pciMod = MV_PCI_MOD_HOST;+        }+        else if (PCI_IF_MODE_DEVICE == pciIfmode)+        {+            pciMod = MV_PCI_MOD_DEVICE;+        }+        else+        {+            mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n", +                        __FUNCTION__, pciIf, pciIfmode);+            return MV_FAIL;+        }+        +        return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);+		#else+		return MV_OK;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		+        MV_PEX_TYPE pexType;+		+        if (PCI_IF_MODE_HOST == pciIfmode)+        {+            pexType = MV_PEX_ROOT_COMPLEX;+        }+        else if (PCI_IF_MODE_DEVICE == pciIfmode)+        {+            pexType = MV_PEX_END_POINT;+        }+        else+        {+            mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \+                       " end point\n", __FUNCTION__, pciIf, pciIfmode);+            return MV_FAIL;+        }+		return mvPexInit(pciIf - MV_PEX_START_IF, pexType);++		#else+		return MV_OK;+		#endif++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return MV_FAIL;++}++/* PCI configuration space read write */++/*******************************************************************************+* mvPciConfigRead - Read from configuration space+*+* DESCRIPTION:+*       This function performs a 32 bit read from PCI configuration space.+*       It supports both type 0 and type 1 of Configuration Transactions +*       (local and over bridge). In order to read from local bus segment, use +*       bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers +*       will result configuration transaction of type 1 (over bridge).+*+* INPUT:+*       pciIf   - PCI interface number.+*       bus     - PCI segment bus number.+*       dev     - PCI device number.+*       func    - Function number.+*       regOffs - Register offset.       +*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit register data, 0xffffffff on error+*+*******************************************************************************/+MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func, +                        MV_U32 regOff)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciConfigRead(pciIf - MV_PCI_START_IF,+								bus,+								dev, +                                func,+								regOff);+		#else+		return 0xffffffff;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexConfigRead(pciIf - MV_PEX_START_IF,+								bus,+								dev, +                                func,+								regOff);+		#else+		return 0xffffffff;+		#endif++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return 0;++}++/*******************************************************************************+* mvPciConfigWrite - Write to configuration space+*+* DESCRIPTION:+*       This function performs a 32 bit write to PCI configuration space.+*       It supports both type 0 and type 1 of Configuration Transactions +*       (local and over bridge). In order to write to local bus segment, use +*       bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers +*       will result configuration transaction of type 1 (over bridge).+*+* INPUT:+*       pciIf   - PCI interface number.+*       bus     - PCI segment bus number.+*       dev     - PCI device number.+*       func    - Function number.+*       regOffs - Register offset.       +*       data    - 32bit data.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, +                           MV_U32 func, MV_U32 regOff, MV_U32 data)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciConfigWrite(pciIf - MV_PCI_START_IF,+								bus,+								dev, +                                func,+								regOff,+								data);+		#else+		return MV_OK;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexConfigWrite(pciIf - MV_PEX_START_IF,+								bus,+								dev, +                                func,+								regOff,+								data);+		#else+		return MV_OK;+		#endif++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return MV_FAIL;++}++/*******************************************************************************+* mvPciMasterEnable - Enable/disale PCI interface master transactions.+*+* DESCRIPTION:+*       This function performs read modified write to PCI command status +*       (offset 0x4) to set/reset bit 2. After this bit is set, the PCI +*       master is allowed to gain ownership on the bus, otherwise it is +*       incapable to do so.+*+* INPUT:+*       pciIf  - PCI interface number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)+{++	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciMasterEnable(pciIf - MV_PCI_START_IF,+								enable);+		#else+		return MV_OK;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexMasterEnable(pciIf - MV_PEX_START_IF,+								enable);+		#else+		return MV_OK;+		#endif+	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return MV_FAIL;++}+++/*******************************************************************************+* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.+*+* DESCRIPTION:+*       This function performs read modified write to PCI command status +*       (offset 0x4) to set/reset bit 0 and 1. After those bits are set, +*       the PCI slave is allowed to respond to PCI IO space access (bit 0) +*       and PCI memory space access (bit 1). +*+* INPUT:+*       pciIf  - PCI interface number.+*       dev     - PCI device number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)+{++	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,+								enable);+		#else+		return MV_OK;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,+								enable);+		#else+		return MV_OK;+		#endif+	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return MV_FAIL;++}++/*******************************************************************************+* mvPciLocalBusNumSet - Set PCI interface local bus number.+*+* DESCRIPTION:+*       This function sets given PCI interface its local bus number.+*       Note: In case the PCI interface is PCI-X, the information is read-only.+*+* INPUT:+*       pciIf  - PCI interface number.+*       busNum - Bus number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_NOT_ALLOWED in case PCI interface is PCI-X. +*		MV_BAD_PARAM on bad parameters ,+*       otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,+								busNum);	+		#else+		return MV_OK;+		#endif+    }+    else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,+								busNum);+		#else+		return MV_OK;+		#endif+	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return MV_FAIL;++}++/*******************************************************************************+* mvPciLocalBusNumGet - Get PCI interface local bus number.+*+* DESCRIPTION:+*       This function gets the local bus number of a given PCI interface.+*+* INPUT:+*       pciIf  - PCI interface number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Local bus number.0xffffffff on Error+*+*******************************************************************************/+MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);+		#else+		return 0xFFFFFFFF;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);+		#else+		return 0xFFFFFFFF;+		#endif++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);+	}++	return 0;++}+++/*******************************************************************************+* mvPciLocalDevNumSet - Set PCI interface local device number.+*+* DESCRIPTION:+*       This function sets given PCI interface its local device number.+*       Note: In case the PCI interface is PCI-X, the information is read-only.+*+* INPUT:+*       pciIf  - PCI interface number.+*       devNum - Device number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,+*       otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,+								devNum);	+		#else+		return MV_OK;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,+								devNum);+		#else+		return MV_OK;+		#endif+	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return MV_FAIL;++}++/*******************************************************************************+* mvPciLocalDevNumGet - Get PCI interface local device number.+*+* DESCRIPTION:+*       This function gets the local device number of a given PCI interface.+*+* INPUT:+*       pciIf  - PCI interface number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Local device number. 0xffffffff on Error+*+*******************************************************************************/+MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)+{+	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		#if defined(MV_INCLUDE_PCI)+		return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);+		#else+		return 0xFFFFFFFF;+		#endif+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		#if defined(MV_INCLUDE_PEX)+		return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);+		#else+		return 0xFFFFFFFF;+		#endif++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return 0;++}++/*******************************************************************************+* mvPciIfTypeGet - +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/++PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)+{++	if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))+	{+		return PCI_IF_TYPE_CONVEN_PCIX;+	}+	else if ((pciIf >= MV_PEX_START_IF) &&+			 (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))+	{+		return PCI_IF_TYPE_PEX;++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return 0xffffffff;++}++/*******************************************************************************+* mvPciIfTypeGet - +*+* DESCRIPTION:+*+* INPUT:+*+* OUTPUT:+*       None.+*+* RETURN:+*+*******************************************************************************/++MV_U32  mvPciRealIfNumGet(MV_U32 pciIf)+{++	PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);++	if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)+	{+		return (pciIf - MV_PCI_START_IF);+	}+	else if (PCI_IF_TYPE_PEX == pciIfType)+	{+		return (pciIf - MV_PEX_START_IF);++	}+	else+	{+		mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);+	}++	return 0xffffffff;++}+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h	2010-11-09 20:28:11.552495455 +0100@@ -0,0 +1,134 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCPCIIFH+#define __INCPCIIFH++#include "mvSysHwConfig.h"+#include "pci-if/mvPciIfRegs.h"+#if defined(MV_INCLUDE_PEX)+#include "pex/mvPex.h"+#endif+#if defined(MV_INCLUDE_PCI)+#include "pci/mvPci.h"+#endif+#include "ctrlEnv/mvCtrlEnvLib.h"+#include "ctrlEnv/mvCtrlEnvAddrDec.h"++typedef enum _mvPCIIfType+{+	PCI_IF_TYPE_CONVEN_PCIX,+	PCI_IF_TYPE_PEX++}PCI_IF_TYPE;++typedef enum _mvPCIIfMode+{+	PCI_IF_MODE_HOST,+	PCI_IF_MODE_DEVICE+}PCI_IF_MODE;+++/* Global Functions prototypes */++/* mvPciIfInit - Initialize PCI interfaces*/+MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);++/* mvPciIfConfigRead - Read from configuration space */+MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,+						MV_U32 func,MV_U32 regOff);++/* mvPciIfConfigWrite - Write to configuration space */+MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,+                           MV_U32 func, MV_U32 regOff, MV_U32 data);++/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/+MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);++/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/+MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, +							 MV_BOOL enable);++/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/+MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);++/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/+MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);++/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/+MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);++/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/+MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);++/* mvPciIfTypeGet - Get PCI If type*/+PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);++MV_U32  mvPciRealIfNumGet(MV_U32 pciIf);++/* mvPciIfAddrDecShow - Display address decode windows attributes */+MV_VOID mvPciIfAddrDecShow(MV_VOID);++#endif /* #ifndef __INCPCIIFH */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h	2010-11-09 20:28:11.592495403 +0100@@ -0,0 +1,245 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCPCIIFREGSH+#define __INCPCIIFREGSH+++/* defines */+#define MAX_PCI_DEVICES         32+#define MAX_PCI_FUNCS           8+#define MAX_PCI_BUSSES          128++/***************************************/+/* PCI Configuration registers */+/***************************************/++/*********************************************/+/* PCI Configuration, Function 0, Registers  */+/*********************************************/+++/* Standard registers */+#define PCI_DEVICE_AND_VENDOR_ID					0x000+#define PCI_STATUS_AND_COMMAND						0x004+#define PCI_CLASS_CODE_AND_REVISION_ID			    0x008+#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE		0x00C+#define PCI_MEMORY_BAR_BASE_ADDR(barNum)		 	(0x010 + ((barNum) << 2))+#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID		 	0x02C+#define PCI_EXPANSION_ROM_BASE_ADDR_REG			    0x030+#define PCI_CAPABILTY_LIST_POINTER			        0x034+#define PCI_INTERRUPT_PIN_AND_LINE					0x03C+++/* PCI Device and Vendor ID Register (PDVIR) */+#define PDVIR_VEN_ID_OFFS			0 	/* Vendor ID */+#define PDVIR_VEN_ID_MASK			(0xffff << PDVIR_VEN_ID_OFFS)++#define PDVIR_DEV_ID_OFFS			16	/* Device ID */+#define PDVIR_DEV_ID_MASK  			(0xffff << PDVIR_DEV_ID_OFFS)++/* PCI Status and Command Register (PSCR) */+#define PSCR_IO_EN			BIT0 	/* IO Enable 							  */+#define PSCR_MEM_EN			BIT1	/* Memory Enable 						  */+#define PSCR_MASTER_EN		BIT2	/* Master Enable 						  */+#define PSCR_SPECIAL_EN		BIT3	/* Special Cycle Enable 				  */+#define PSCR_MEM_WRI_INV	BIT4	/* Memory Write and Invalidate Enable	  */+#define PSCR_VGA			BIT5	/* VGA Palette Snoops 					  */+#define PSCR_PERR_EN		BIT6	/* Parity Errors Respond Enable 		  */+#define PSCR_ADDR_STEP   	BIT7    /* Address Stepping Enable (Wait Cycle En)*/+#define PSCR_SERR_EN		BIT8	/* Ability to assert SERR# line			  */+#define PSCR_FAST_BTB_EN	BIT9	/* generate fast back-to-back transactions*/+#define PSCR_CAP_LIST		BIT20	/* Capability List Support 				  */+#define PSCR_66MHZ_EN		BIT21   /* 66 MHz Capable 						  */+#define PSCR_UDF_EN			BIT22   /* User definable features 				  */+#define PSCR_TAR_FAST_BB 	BIT23   /* fast back-to-back transactions capable */+#define PSCR_DATA_PERR		BIT24   /* Data Parity reported 				  */++#define PSCR_DEVSEL_TIM_OFFS 	25  /* DEVSEL timing */+#define PSCR_DEVSEL_TIM_MASK 	(0x3 << PSCR_DEVSEL_TIM_OFFS)+#define PSCR_DEVSEL_TIM_FAST	(0x0 << PSCR_DEVSEL_TIM_OFFS)+#define PSCR_DEVSEL_TIM_MED 	(0x1 << PSCR_DEVSEL_TIM_OFFS)+#define PSCR_DEVSEL_TIM_SLOW 	(0x2 << PSCR_DEVSEL_TIM_OFFS)++#define PSCR_SLAVE_TABORT	BIT27	/* Signalled Target Abort 	*/+#define PSCR_MASTER_TABORT	BIT28	/* Recieved Target Abort 	*/+#define PSCR_MABORT			BIT29	/* Recieved Master Abort 	*/+#define PSCR_SYSERR			BIT30	/* Signalled system error 	*/+#define PSCR_DET_PARERR		BIT31	/* Detect Parity Error 		*/++/* 	PCI configuration register offset=0x08 fields +	(PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) 				*/++#define PCCRIR_REVID_OFFS		0		/* Revision ID */+#define PCCRIR_REVID_MASK		(0xff << PCCRIR_REVID_OFFS)++#define PCCRIR_FULL_CLASS_OFFS	8		/* Full Class Code */+#define PCCRIR_FULL_CLASS_MASK	(0xffffff << PCCRIR_FULL_CLASS_OFFS)++#define PCCRIR_PROGIF_OFFS		8		/* Prog .I/F*/+#define PCCRIR_PROGIF_MASK		(0xff << PCCRIR_PROGIF_OFFS)++#define PCCRIR_SUB_CLASS_OFFS	16		/* Sub Class*/+#define PCCRIR_SUB_CLASS_MASK	(0xff << PCCRIR_SUB_CLASS_OFFS)++#define PCCRIR_BASE_CLASS_OFFS	24		/* Base Class*/+#define PCCRIR_BASE_CLASS_MASK	(0xff << PCCRIR_BASE_CLASS_OFFS)++/* 	PCI configuration register offset=0x0C fields +	(PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) 				*/++#define PBHTLTCLR_CACHELINE_OFFS		0	/* Specifies the cache line size */+#define PBHTLTCLR_CACHELINE_MASK		(0xff << PBHTLTCLR_CACHELINE_OFFS)+	+#define PBHTLTCLR_LATTIMER_OFFS			8	/* latency timer */+#define PBHTLTCLR_LATTIMER_MASK			(0xff << PBHTLTCLR_LATTIMER_OFFS)++#define PBHTLTCLR_HEADTYPE_FULL_OFFS	16	/* Full Header Type */+#define PBHTLTCLR_HEADTYPE_FULL_MASK	(0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)++#define PBHTLTCLR_MULTI_FUNC			BIT23	/* Multi/Single function */++#define PBHTLTCLR_HEADER_OFFS			16		/* Header type */+#define PBHTLTCLR_HEADER_MASK			(0x7f << PBHTLTCLR_HEADER_OFFS)+#define PBHTLTCLR_HEADER_STANDARD		(0x0 << PBHTLTCLR_HEADER_OFFS)+#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE	(0x1 << PBHTLTCLR_HEADER_OFFS)+++#define PBHTLTCLR_BISTCOMP_OFFS		24	/* BIST Completion Code */+#define PBHTLTCLR_BISTCOMP_MASK		(0xf << PBHTLTCLR_BISTCOMP_OFFS)++#define PBHTLTCLR_BISTACT			BIT30	/* BIST Activate bit */+#define PBHTLTCLR_BISTCAP			BIT31	/* BIST Capable Bit */+++/* PCI Bar Base Low Register (PBBLR) */+#define PBBLR_IOSPACE			BIT0	/* Memory Space Indicator */++#define PBBLR_TYPE_OFFS			1	   /* BAR Type/Init Val. */ +#define PBBLR_TYPE_MASK			(0x3 << PBBLR_TYPE_OFFS)+#define PBBLR_TYPE_32BIT_ADDR	(0x0 << PBBLR_TYPE_OFFS)+#define PBBLR_TYPE_64BIT_ADDR	(0x2 << PBBLR_TYPE_OFFS)++#define PBBLR_PREFETCH_EN		BIT3 	/* Prefetch Enable */++				+#define PBBLR_MEM_BASE_OFFS		4	/* Memory Bar Base address. Corresponds to+									address bits [31:4] */+#define PBBLR_MEM_BASE_MASK		(0xfffffff << PBBLR_MEM_BASE_OFFS)++#define PBBLR_IO_BASE_OFFS		2	/* IO Bar Base address. Corresponds to +										address bits [31:2] */+#define PBBLR_IO_BASE_MASK		(0x3fffffff << PBBLR_IO_BASE_OFFS)+++#define PBBLR_BASE_OFFS			12		/* Base address. Address bits [31:12] */+#define PBBLR_BASE_MASK			(0xfffff << PBBLR_BASE_OFFS)+#define PBBLR_BASE_ALIGNMET		(1 << PBBLR_BASE_OFFS)+++/* PCI Bar Base High Fegister (PBBHR) */+#define PBBHR_BASE_OFFS			0		/* Base address. Address bits [31:12] */+#define PBBHR_BASE_MASK			(0xffffffff << PBBHR_BASE_OFFS)+++/* 	PCI configuration register offset=0x2C fields +	(PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) 				*/++#define PSISVIR_VENID_OFFS	0	/* Subsystem Manufacturer Vendor ID Number */+#define PSISVIR_VENID_MASK	(0xffff << PSISVIR_VENID_OFFS)++#define PSISVIR_DEVID_OFFS	16	/* Subsystem Device ID Number */+#define PSISVIR_DEVID_MASK	(0xffff << PSISVIR_DEVID_OFFS)++/* 	PCI configuration register offset=0x30 fields +	(PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) 				*/++#define PERBAR_EXPROMEN		BIT0	/* Expansion ROM Enable */++#define PERBAR_BASE_OFFS		12		/* Expansion ROM Base Address */+#define PERBAR_BASE_MASK		(0xfffff << PERBAR_BASE_OFFS) 	++/* 	PCI configuration register offset=0x34 fields +	(PCI_CAPABILTY_LIST_POINTER)(PCLP) 				*/++#define PCLPR_CAPPTR_OFFS	0		/* Capability List Pointer */+#define PCLPR_CAPPTR_MASK	(0xff << PCLPR_CAPPTR_OFFS)++/* 	PCI configuration register offset=0x3C fields +	(PCI_INTERRUPT_PIN_AND_LINE)(PIPL) 				*/++#define PIPLR_INTLINE_OFFS	0	/* Interrupt line (IRQ) */+#define PIPLR_INTLINE_MASK	(0xff << PIPLR_INTLINE_OFFS)++#define PIPLR_INTPIN_OFFS	8	/* interrupt pin (A,B,C,D) */+#define PIPLR_INTPIN_MASK	(0xff << PIPLR_INTPIN_OFFS)++#define PIPLR_MINGRANT_OFFS	16	/* Minimum Grant on 250 nano seconds units */+#define PIPLR_MINGRANT_MASK	(0xff << PIPLR_MINGRANT_OFFS)++#define PIPLR_MAXLATEN_OFFS	24	/* Maximum latency on 250 nano seconds units */+#define PIPLR_MAXLATEN_MASK	(0xff << PIPLR_MAXLATEN_OFFS)++#endif /* #ifndef __INCPCIIFREGSH */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c	2010-11-09 20:28:11.632495445 +0100@@ -0,0 +1,1006 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++/* includes */+#include "mvPciUtils.h"++#include "ctrlEnv/mvCtrlEnvLib.h"++/* #define MV_DEBUG */+/* defines  */+#ifdef MV_DEBUG+	#define DB(x)	x+	#define mvOsPrintf printf+#else+	#define DB(x)+#endif++/*+This module only support scanning of Header type 00h of pci devices+There is no suppotr for Header type 01h of pci devices  ( PCI bridges )+*/+++static MV_STATUS pciDetectDevice(MV_U32 pciIf,+   								 MV_U32 bus,+   								 MV_U32 dev,+   								 MV_U32 func,+								 MV_PCI_DEVICE *pPciAgent);++static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,+									MV_U32 bus,+									MV_U32 dev,+									MV_U32 func,+									MV_PCI_DEVICE *pPciAgent);+++++++/*******************************************************************************+* mvPciScan - Scan a PCI interface bus+*+* DESCRIPTION:+* Performs a full scan on a PCI interface and returns all possible details+* on the agents found on the bus.+*+* INPUT:+*       pciIf       - PCI Interface+*       pPciAgents 	- Pointer to an Array of the pci agents to be detected+*		pPciAgentsNum - pPciAgents array maximum number of elements+*+* OUTPUT:+*       pPciAgents - Array of the pci agents detected on the bus+*		pPciAgentsNum - Number of pci agents detected on the bus+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/++MV_STATUS mvPciScan(MV_U32 pciIf,+					MV_PCI_DEVICE *pPciAgents,+					MV_U32 *pPciAgentsNum)+{++	MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;+    MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);+    MV_PCI_DEVICE *pPciDevice;+	MV_PCI_DEVICE *pMainDevice;++	DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));+	/* Parameter checking   */+	if (pciIf >= mvCtrlPexMaxIfGet())+	{+		DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));+		return MV_BAD_PARAM;+	}+	if (NULL == pPciAgents)+	{+		DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));+		return MV_BAD_PARAM;+	}+	if (NULL == pPciAgentsNum)+	{+		DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));+		return MV_BAD_PARAM;+	}+++	DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));+	/* Master enable the MV PCI master */+	if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))+	{+		DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed  \n"));+		return MV_ERROR;++	}++	DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));++	/* go through all busses */+	for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)+	{+		/* go through all possible devices on the local bus */+		for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)+		{+			/* always start with function equal to zero */+			funcIndex=0;++			pPciDevice=&pPciAgents[detectedDevNum];+			DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));++			if (MV_ERROR == pciDetectDevice(pciIf,+										   busIndex,+										   devIndex,+										   funcIndex,+										   pPciDevice))+			{+				/* no device detected , try the next address */+				continue;+			}++			/* We are here ! means we have detected a device*/+			/* always we start with only one function per device */+			pMainDevice = pPciDevice;+			pPciDevice->funtionsNum = 1;+++			/* move on */+			detectedDevNum++;+++			/* check if we have no more room for a new device */+			if (detectedDevNum == *pPciAgentsNum)+			{+				DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));+				return MV_ERROR;+			}++			/* check the detected device if it is a multi functional device then+			scan all device functions*/+			if (pPciDevice->isMultiFunction == MV_TRUE)+			{+				/* start with function number 1 because we have already detected+				function 0 */+				for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)+				{+					pPciDevice=&pPciAgents[detectedDevNum];++					if (MV_ERROR == pciDetectDevice(pciIf,+												   busIndex,+												   devIndex,+												   funcIndex,+												   pPciDevice))+					{+						/* no device detected means no more functions !*/+						continue;+					}+					/* We are here ! means we have detected a device */++					/* move on */+					pMainDevice->funtionsNum++;+					detectedDevNum++;++					/* check if we have no more room for a new device */+					if (detectedDevNum == *pPciAgentsNum)+					{+						DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));+						return MV_ERROR;+					}+++				}+			}++		}++	}++	/* return the number of devices actually detected on the bus ! */+	*pPciAgentsNum = detectedDevNum;++	return MV_OK;++}+++/*******************************************************************************+* pciDetectDevice - Detect a pci device parameters+*+* DESCRIPTION:+*	This function detect if a pci agent exist on certain address !+*   and if exists then it fills all possible information on the+*   agent+*+* INPUT:+*       pciIf       - PCI Interface+*		bus		-	Bus number+*		dev		- 	Device number+*		func	-	Function number+*+*+*+* OUTPUT:+*       pPciAgent - pointer to the pci agent filled with its information+*+* RETURN:+*       MV_ERROR if no device , MV_OK otherwise+*+*******************************************************************************/++static MV_STATUS pciDetectDevice(MV_U32 pciIf,+   								 MV_U32 bus,+   								 MV_U32 dev,+   								 MV_U32 func,+								 MV_PCI_DEVICE *pPciAgent)+{+	MV_U32 pciData;++	/* no Parameters checking ! because it is static function and it is assumed+	that all parameters were checked in the calling function */+++	/* Try read the PCI Vendor ID and Device ID */++	/*  We will scan only ourselves and the PCI slots that exist on the+		board, because we may have a case that we have one slot that has+		a Cardbus connector, and because CardBus answers all IDsels we want+		to scan only this slot and ourseleves.++	*/+	#if defined(MV_INCLUDE_PCI)+	if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&+					(DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&+					(DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&+					(DB_88F5181_DDR1_MNG != mvBoardIdGet()))+    	{++			if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)+			{+				return MV_ERROR;+			}+	}+	#endif /* defined(MV_INCLUDE_PCI) */++	pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);++	if (PCI_ERROR_CODE == pciData)+	{+		/* no device exist */+		return MV_ERROR;+	}++	/* we are here ! means a device is detected */++	/* fill basic information */+	pPciAgent->busNumber=bus;+	pPciAgent->deviceNum=dev;+	pPciAgent->function=func;++	/* Fill the PCI Vendor ID and Device ID */++	pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;+	pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;++	/* Read Status and command */+	pciData = mvPciIfConfigRead(pciIf,+							  bus,dev,func,+							  PCI_STATUS_AND_COMMAND);+++	/* Fill related Status and Command information*/++	if (pciData & PSCR_TAR_FAST_BB)+	{+		pPciAgent->isFastB2BCapable = MV_TRUE;+	}+	else+	{+		pPciAgent->isFastB2BCapable = MV_FALSE;+	}++	if (pciData & PSCR_CAP_LIST)+	{+		pPciAgent->isCapListSupport=MV_TRUE;+	}+	else+	{+		pPciAgent->isCapListSupport=MV_FALSE;+	}++	if (pciData & PSCR_66MHZ_EN)+	{+		pPciAgent->is66MHZCapable=MV_TRUE;+	}+	else+	{+		pPciAgent->is66MHZCapable=MV_FALSE;+	}++	/* Read Class Code and Revision */+	pciData = mvPciIfConfigRead(pciIf,+							  bus,dev,func,+							  PCI_CLASS_CODE_AND_REVISION_ID);+++	pPciAgent->baseClassCode =+		(pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;++	pPciAgent->subClassCode =+		(pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;++	pPciAgent->progIf =+		(pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;++	pPciAgent->revisionID =+		(pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;++	/* Read  PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */+	pciData = mvPciIfConfigRead(pciIf,+							  bus,dev,func,+							  PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);++++	pPciAgent->pciCacheLine=+		(pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;+	pPciAgent->pciLatencyTimer=+		(pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;++	switch (pciData & PBHTLTCLR_HEADER_MASK)+	{+	case PBHTLTCLR_HEADER_STANDARD:++		pPciAgent->pciHeader=MV_PCI_STANDARD;+		break;+	case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:++		pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;+		break;++	}++	if (pciData & PBHTLTCLR_MULTI_FUNC)+	{+		pPciAgent->isMultiFunction=MV_TRUE;+	}+	else+	{+		pPciAgent->isMultiFunction=MV_FALSE;+	}++	if (pciData & PBHTLTCLR_BISTCAP)+	{+		pPciAgent->isBISTCapable=MV_TRUE;+	}+	else+	{+		pPciAgent->isBISTCapable=MV_FALSE;+	}+++	/* read this device pci bars */++	pciDetectDeviceBars(pciIf,+					  bus,dev,func,+	 				 pPciAgent);+++	/* check if we are bridge*/+	if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&+		(pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))+	{++		/* Read  P2P_BUSSES_NUM */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  P2P_BUSSES_NUM);++		pPciAgent->p2pPrimBusNum =+			(pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;++		pPciAgent->p2pSecBusNum =+			(pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;++		pPciAgent->p2pSubBusNum =+			(pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;++		pPciAgent->p2pSecLatencyTimer =+			(pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;++		/* Read  P2P_IO_BASE_LIMIT_SEC_STATUS */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  P2P_IO_BASE_LIMIT_SEC_STATUS);++		pPciAgent->p2pSecStatus =+			(pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;+++		pPciAgent->p2pIObase =+			(pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;++		/* clear low address (should be zero)*/+		pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;++		pPciAgent->p2pIOLimit =+			(pciData & PIBLSS_IO_LIMIT_MASK);++		/* fill low address with 0xfff */+		pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;+++		switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)+		{+		case PIBLSS_ADD_CAP_16BIT:++			pPciAgent->bIO32 = MV_FALSE;++			break;+		case PIBLSS_ADD_CAP_32BIT:++			pPciAgent->bIO32 = MV_TRUE;++			/* Read  P2P_IO_BASE_LIMIT_UPPER_16 */+			pciData = mvPciIfConfigRead(pciIf,+									  bus,dev,func,+									  P2P_IO_BASE_LIMIT_UPPER_16);++			pPciAgent->p2pIObase |=+				(pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;+++			pPciAgent->p2pIOLimit |=+				(pciData & PRBU_IO_UPP_LIMIT_MASK);++			break;++		}+++		/* Read  P2P_MEM_BASE_LIMIT */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  P2P_MEM_BASE_LIMIT);++		pPciAgent->p2pMemBase =+			(pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;++		/* clear low address */+		pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;++		pPciAgent->p2pMemLimit =+			(pciData & PMBL_MEM_LIMIT_MASK);++		/* add 0xfffff */+		pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;+++		/* Read  P2P_PREF_MEM_BASE_LIMIT */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  P2P_PREF_MEM_BASE_LIMIT);+++		pPciAgent->p2pPrefMemBase =+			(pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;++		/* get high address only */+		pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;++++		pPciAgent->p2pPrefMemLimit =+			(pciData & PRMBL_PREF_MEM_LIMIT_MASK);++		/* add 0xfffff */+		pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;++		switch (pciData & PRMBL_ADD_CAP_MASK)+		{+		case PRMBL_ADD_CAP_32BIT:++			pPciAgent->bPrefMem64 = MV_FALSE;++			/* Read  P2P_PREF_BASE_UPPER_32 */+			pPciAgent->p2pPrefBaseUpper32Bits = 0;++			/* Read  P2P_PREF_LIMIT_UPPER_32 */+			pPciAgent->p2pPrefLimitUpper32Bits = 0;++			break;+		case PRMBL_ADD_CAP_64BIT:++			pPciAgent->bPrefMem64 = MV_TRUE;++			/* Read  P2P_PREF_BASE_UPPER_32 */+			pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,+									  bus,dev,func,+									  P2P_PREF_BASE_UPPER_32);++			/* Read  P2P_PREF_LIMIT_UPPER_32 */+			pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,+									  bus,dev,func,+									  P2P_PREF_LIMIT_UPPER_32);++			break;++		}++	}+	else /* no bridge */+	{+		/* Read  PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);+++		pPciAgent->subSysVenID =+			(pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;+		pPciAgent->subSysID =+			(pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;+++		/* Read  PCI_EXPANSION_ROM_BASE_ADDR_REG */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  PCI_EXPANSION_ROM_BASE_ADDR_REG);+++		if (pciData & PERBAR_EXPROMEN)+		{+			pPciAgent->isExpRom = MV_TRUE;+		}+		else+		{+			pPciAgent->isExpRom = MV_FALSE;+		}++		pPciAgent->expRomAddr =+			(pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;++	}+++	if (MV_TRUE == pPciAgent->isCapListSupport)+	{+		/* Read  PCI_CAPABILTY_LIST_POINTER */+		pciData = mvPciIfConfigRead(pciIf,+								  bus,dev,func,+								  PCI_CAPABILTY_LIST_POINTER);++		pPciAgent->capListPointer =+			(pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;++	}++	/* Read  PCI_INTERRUPT_PIN_AND_LINE */+	pciData = mvPciIfConfigRead(pciIf,+							  bus,dev,func,+							  PCI_INTERRUPT_PIN_AND_LINE);+++	pPciAgent->irqLine=+		(pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;++	pPciAgent->intPin=+		(MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;++	pPciAgent->minGrant=+		(pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;+	pPciAgent->maxLatency=+		(pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;++	mvPciClassNameGet(pPciAgent->baseClassCode,+					  (MV_8 *)pPciAgent->type);++	return MV_OK;+++}++/*******************************************************************************+* pciDetectDeviceBars - Detect a pci device bars+*+* DESCRIPTION:+*	This function detects all pci agent bars+*+* INPUT:+*       pciIf       - PCI Interface+*		bus		-	Bus number+*		dev		- 	Device number+*		func	-	Function number+*+*+*+* OUTPUT:+*       pPciAgent - pointer to the pci agent filled with its information+*+* RETURN:+*       detected bars number+*+*******************************************************************************/+static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,+									MV_U32 bus,+									MV_U32 dev,+									MV_U32 func,+									MV_PCI_DEVICE *pPciAgent)+{+	MV_U32 pciData,barIndex,detectedBar=0;+	MV_U32 tmpBaseHigh=0,tmpBaseLow=0;+	MV_U32 pciMaxBars=0;++	pPciAgent->barsNum=0;++	/* check if we are bridge*/+	if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&+		(pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))+	{+		pciMaxBars = 2;+	}+	else /* no bridge */+	{+		pciMaxBars = 6;+	}++	/* read this device pci bars */+	for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )+	{+		/* Read  PCI_MEMORY_BAR_BASE_ADDR */+		tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,+									   bus,dev,func,+						               PCI_MEMORY_BAR_BASE_ADDR(barIndex));++		pPciAgent->pciBar[detectedBar].barOffset =+			PCI_MEMORY_BAR_BASE_ADDR(barIndex);++		/* check if the bar is 32bit or 64bit bar */+		switch (pciData & PBBLR_TYPE_MASK)+		{+		case PBBLR_TYPE_32BIT_ADDR:+			pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;+			break;+		case PBBLR_TYPE_64BIT_ADDR:+			pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;+			break;++		}++		/* check if it is memory or IO bar */+		if (pciData & PBBLR_IOSPACE)+		{+			pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;+		}+		else+		{+			pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;+		}++		/* if it is memory bar then check if it is prefetchable */+		if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)+		{+			if (pciData & PBBLR_PREFETCH_EN)+			{+				pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;+			}+			else+			{+				pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;+			}++            pPciAgent->pciBar[detectedBar].barBaseLow =+				pciData & PBBLR_MEM_BASE_MASK;+++		}+		else /* IO Bar */+		{+			pPciAgent->pciBar[detectedBar].barBaseLow =+				pciData & PBBLR_IO_BASE_MASK;++		}++		pPciAgent->pciBar[detectedBar].barBaseHigh=0;++		if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)+		{+			barIndex++;++			tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =+				mvPciIfConfigRead(pciIf,+								bus,dev,func,+								PCI_MEMORY_BAR_BASE_ADDR(barIndex));+++		}++		/* calculating full base address (64bit) */+		pPciAgent->pciBar[detectedBar].barBaseAddr =+			(MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;++		pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;++		pPciAgent->pciBar[detectedBar].barBaseAddr |=+			(MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;++++		/* get the sizes of the the bar */++		pPciAgent->pciBar[detectedBar].barSizeHigh=0;++		if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&+			(PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))++		{+			/* write oxffffffff to the bar to get the size */+			/* start with sizelow ( original value was saved in tmpBaseLow ) */+			mvPciIfConfigWrite(pciIf,+							bus,dev,func,+							PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),+							0xffffffff);++			/* read size */+			pPciAgent->pciBar[detectedBar].barSizeLow =+				mvPciIfConfigRead(pciIf,+								bus,dev,func,+								PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));++++			/* restore original value */+			mvPciIfConfigWrite(pciIf,+							bus,dev,func,+							PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),+							tmpBaseLow);+++			/* now do the same for BaseHigh */++			/* write oxffffffff to the bar to get the size */+			mvPciIfConfigWrite(pciIf,+							bus,dev,func,+							PCI_MEMORY_BAR_BASE_ADDR(barIndex),+							0xffffffff);++			/* read size */+			pPciAgent->pciBar[detectedBar].barSizeHigh =+				mvPciIfConfigRead(pciIf,+								bus,dev,func,+								PCI_MEMORY_BAR_BASE_ADDR(barIndex));++			/* restore original value */+			mvPciIfConfigWrite(pciIf,+							bus,dev,func,+							PCI_MEMORY_BAR_BASE_ADDR(barIndex),+							tmpBaseHigh);++			if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&+				(0 == pPciAgent->pciBar[detectedBar].barSizeHigh))+			{+				/* this bar is not applicable for this device,+				   ignore all previous settings and check the next bar*/++				/* we though this was a 64bit bar , and it seems this+				   was wrong ! so decrement barIndex */+				barIndex--;+				continue;+			}++			/* calculate the full 64 bit size  */++			if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)+			{+				pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;++				pPciAgent->pciBar[detectedBar].barSizeLow =+					~pPciAgent->pciBar[detectedBar].barSizeLow + 1;++				pPciAgent->pciBar[detectedBar].barSizeHigh = 0;++			}+			else+			{++				pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;++				pPciAgent->pciBar[detectedBar].barSizeLow =+					~pPciAgent->pciBar[detectedBar].barSizeLow + 1;++				pPciAgent->pciBar[detectedBar].barSizeHigh = 0;++			}++++		}+		else /* 32bit bar */+		{+			/* write oxffffffff to the bar to get the size */+			mvPciIfConfigWrite(pciIf,+							bus,dev,func,+							PCI_MEMORY_BAR_BASE_ADDR(barIndex),+							0xffffffff);++			/* read size */+			pPciAgent->pciBar[detectedBar].barSizeLow =+				mvPciIfConfigRead(pciIf,+								bus,dev,func,+								PCI_MEMORY_BAR_BASE_ADDR(barIndex));++			if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)+			{+				/* this bar is not applicable for this device,+				   ignore all previous settings and check the next bar*/+				continue;+			}+++			/* restore original value */+			mvPciIfConfigWrite(pciIf,+							bus,dev,func,+							PCI_MEMORY_BAR_BASE_ADDR(barIndex),+							tmpBaseLow);++		/* calculate size low */++			if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)+			{+				pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;+			}+			else+			{+				pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;+			}++			pPciAgent->pciBar[detectedBar].barSizeLow =+				~pPciAgent->pciBar[detectedBar].barSizeLow + 1;++			pPciAgent->pciBar[detectedBar].barSizeHigh = 0;+			pPciAgent->pciBar[detectedBar].barSize =+				(MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;+++		}++		/* we are here ! this means we have already detected a bar for+		this device , now move on */++		detectedBar++;+		pPciAgent->barsNum++;+	}++	return detectedBar;+}+++/*******************************************************************************+* mvPciClassNameGet - get PCI  class name+*+* DESCRIPTION:+*		This function returns the PCI class name+*+* INPUT:+*       baseClassCode       - Base Class Code.+*+* OUTPUT:+*       pType - the class name+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)+{++    switch(baseClassCode)+    {+        case 0x0:+            strcpy(pType,"Old generation device");+            break;+        case 0x1:+            strcpy(pType,"Mass storage controller");+            break;+        case 0x2:+            strcpy(pType,"Network controller");+            break;+        case 0x3:+            strcpy(pType,"Display controller");+            break;+        case 0x4:+            strcpy(pType,"Multimedia device");+            break;+        case 0x5:+            strcpy(pType,"Memory controller");+            break;+        case 0x6:+            strcpy(pType,"Bridge Device");+            break;+        case 0x7:+            strcpy(pType,"Simple Communication controllers");+            break;+        case 0x8:+            strcpy(pType,"Base system peripherals");+            break;+        case 0x9:+            strcpy(pType,"Input Devices");+            break;+        case 0xa:+            strcpy(pType,"Docking stations");+            break;+        case 0xb:+            strcpy(pType,"Processors");+            break;+        case 0xc:+            strcpy(pType,"Serial bus controllers");+            break;+        case 0xd:+            strcpy(pType,"Wireless controllers");+            break;+        case 0xe:+            strcpy(pType,"Intelligent I/O controllers");+            break;+        case 0xf:+            strcpy(pType,"Satellite communication controllers");+            break;+        case 0x10:+            strcpy(pType,"Encryption/Decryption controllers");+            break;+        case 0x11:+            strcpy(pType,"Data acquisition and signal processing controllers");+            break;+        default:+            strcpy(pType,"Unknown device");+            break;+    }++	return MV_OK;++}+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h	2010-11-09 20:28:11.662495451 +0100@@ -0,0 +1,323 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvPciUtilsh+#define __INCmvPciUtilsh++/* +This module only support scanning of Header type 00h of pci devices +There is no suppotr for Header type 01h of pci devices  ( PCI bridges )+*/++/* includes */+#include "mvSysHwConfig.h"+#include "pci-if/mvPciIf.h"+#include "pci/mvPciRegs.h"++++/* PCI base address low bar mask */+#define PCI_ERROR_CODE                      0xffffffff++#define PCI_BRIDGE_CLASS					0x6+#define P2P_BRIDGE_SUB_CLASS_CODE			0x4+++#define P2P_BUSSES_NUM						0x18+#define P2P_IO_BASE_LIMIT_SEC_STATUS		0x1C+#define P2P_MEM_BASE_LIMIT					0x20+#define P2P_PREF_MEM_BASE_LIMIT				0x24+#define P2P_PREF_BASE_UPPER_32				0x28+#define P2P_PREF_LIMIT_UPPER_32				0x2C+#define P2P_IO_BASE_LIMIT_UPPER_16			0x30+#define P2P_EXP_ROM							0x38++/* P2P_BUSSES_NUM  (PBM) */++#define PBM_PRIME_BUS_NUM_OFFS				0+#define PBM_PRIME_BUS_NUM_MASK				(0xff << PBM_PRIME_BUS_NUM_OFFS)++#define PBM_SEC_BUS_NUM_OFFS				8+#define PBM_SEC_BUS_NUM_MASK				(0xff << PBM_SEC_BUS_NUM_OFFS)++#define PBM_SUB_BUS_NUM_OFFS				16+#define PBM_SUB_BUS_NUM_MASK				(0xff << PBM_SUB_BUS_NUM_OFFS)++#define PBM_SEC_LAT_TMR_OFFS				24+#define PBM_SEC_LAT_TMR_MASK				(0xff << PBM_SEC_LAT_TMR_OFFS)++/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */++#define PIBLSS_IO_BASE_OFFS					0+#define PIBLSS_IO_BASE_MASK					(0xff << PIBLSS_IO_BASE_OFFS)++#define PIBLSS_ADD_CAP_OFFS					0+#define PIBLSS_ADD_CAP_MASK 				(0x3 << PIBLSS_ADD_CAP_OFFS)+#define PIBLSS_ADD_CAP_16BIT 				(0x0 << PIBLSS_ADD_CAP_OFFS)+#define PIBLSS_ADD_CAP_32BIT 				(0x1 << PIBLSS_ADD_CAP_OFFS)++#define PIBLSS_LOW_ADDR_OFFS				0+#define PIBLSS_LOW_ADDR_MASK				(0xFFF << PIBLSS_LOW_ADDR_OFFS)++#define PIBLSS_HIGH_ADDR_OFFS				12+#define PIBLSS_HIGH_ADDR_MASK				(0xF << PIBLSS_HIGH_ADDR_OFFS)++#define PIBLSS_IO_LIMIT_OFFS				8+#define PIBLSS_IO_LIMIT_MASK				(0xff << PIBLSS_IO_LIMIT_OFFS)++#define PIBLSS_SEC_STATUS_OFFS				16+#define PIBLSS_SEC_STATUS_MASK				(0xffff << PIBLSS_SEC_STATUS_OFFS)+++/* P2P_MEM_BASE_LIMIT (PMBL)*/++#define PMBL_MEM_BASE_OFFS					0+#define PMBL_MEM_BASE_MASK					(0xffff << PMBL_MEM_BASE_OFFS)++#define PMBL_MEM_LIMIT_OFFS					16+#define PMBL_MEM_LIMIT_MASK					(0xffff << PMBL_MEM_LIMIT_OFFS)+++#define PMBL_LOW_ADDR_OFFS					0+#define PMBL_LOW_ADDR_MASK					(0xFFFFF << PMBL_LOW_ADDR_OFFS)++#define PMBL_HIGH_ADDR_OFFS					20+#define PMBL_HIGH_ADDR_MASK					(0xFFF << PMBL_HIGH_ADDR_OFFS)+++/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */++#define PRMBL_PREF_MEM_BASE_OFFS			0+#define PRMBL_PREF_MEM_BASE_MASK			(0xffff << PRMBL_PREF_MEM_BASE_OFFS)++#define PRMBL_PREF_MEM_LIMIT_OFFS			16+#define PRMBL_PREF_MEM_LIMIT_MASK			(0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)++#define PRMBL_LOW_ADDR_OFFS					0+#define PRMBL_LOW_ADDR_MASK					(0xFFFFF << PRMBL_LOW_ADDR_OFFS)++#define PRMBL_HIGH_ADDR_OFFS				20+#define PRMBL_HIGH_ADDR_MASK				(0xFFF << PRMBL_HIGH_ADDR_OFFS)++#define PRMBL_ADD_CAP_OFFS					0+#define PRMBL_ADD_CAP_MASK					(0xf << PRMBL_ADD_CAP_OFFS)+#define PRMBL_ADD_CAP_32BIT					(0x0 << PRMBL_ADD_CAP_OFFS)+#define PRMBL_ADD_CAP_64BIT					(0x1 << PRMBL_ADD_CAP_OFFS)++/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */++#define PRBU_IO_UPP_BASE_OFFS				0+#define PRBU_IO_UPP_BASE_MASK				(0xffff << PRBU_IO_UPP_BASE_OFFS)++#define PRBU_IO_UPP_LIMIT_OFFS				16+#define PRBU_IO_UPP_LIMIT_MASK				(0xffff << PRBU_IO_UPP_LIMIT_OFFS)+++/* typedefs */++typedef enum _mvPciBarMapping+{+    PCI_MEMORY_BAR, +    PCI_IO_BAR, +    PCI_NO_MAPPING+}MV_PCI_BAR_MAPPING;++typedef enum _mvPciBarType+{+    PCI_32BIT_BAR, +    PCI_64BIT_BAR+}MV_PCI_BAR_TYPE;++typedef enum _mvPciIntPin+{+    MV_PCI_INTA = 1,+    MV_PCI_INTB = 2,+    MV_PCI_INTC = 3,+    MV_PCI_INTD = 4+}MV_PCI_INT_PIN;++typedef enum _mvPciHeader+{+    MV_PCI_STANDARD,+    MV_PCI_PCI2PCI_BRIDGE++}MV_PCI_HEADER;+++/* BAR structure */+typedef struct _pciBar+{+    MV_U32 barOffset;+    MV_U32 barBaseLow;+    MV_U32 barBaseHigh;+    MV_U32 barSizeLow;+    MV_U32 barSizeHigh;+    /* The 'barBaseAddr' is a 64-bit variable+       that will contain the TOTAL base address+       value achived by combining both the 'barBaseLow'+       and the 'barBaseHigh' parameters as follows:++       BIT: 63          31         0+            |           |         |+            barBaseHigh barBaseLow */+    MV_U64 barBaseAddr;+    /* The 'barSize' is a 64-bit variable+       that will contain the TOTAL size achived+       by combining both the 'barSizeLow' and+       the 'barSizeHigh' parameters as follows:++       BIT: 63          31         0+            |           |         |+            barSizeHigh barSizeLow++       NOTE: The total size described above+             is AFTER the size calculation as+             described in PCI spec rev2.2 */+    MV_U64 barSize;+    MV_BOOL            isPrefetchable;+    MV_PCI_BAR_TYPE       barType;+    MV_PCI_BAR_MAPPING    barMapping;+++} PCI_BAR;++/* Device information structure */+typedef struct _mvPciDevice+{+    /* Device specific information */+	MV_U32			busNumber; 	/* Pci agent bus number */+    MV_U32			deviceNum;	/* Pci agent device number */+    MV_U32			function;	/* Pci agent function number */++	MV_U32			venID;		/* Pci agent Vendor ID */+    MV_U32			deviceID;	/* Pci agent Device ID */++    MV_BOOL			isFastB2BCapable;	/* Capability of Fast Back to Back +										   transactions */+	MV_BOOL			isCapListSupport;	/* Support of Capability list */+	MV_BOOL			is66MHZCapable;		/* 66MHZ support */++    MV_U32			baseClassCode;		/* Pci agent base Class Code */+    MV_U32			subClassCode;		/* Pci agent sub Class Code */+    MV_U32			progIf;				/* Pci agent Programing interface */+	MV_U32			revisionID;++    PCI_BAR			pciBar[6]; 			/* Pci agent bar list */++	MV_U32			p2pPrimBusNum;		/* P2P Primary Bus number*/+	MV_U32			p2pSecBusNum;		/* P2P Secondary Bus Number*/+	MV_U32			p2pSubBusNum;		/* P2P Subordinate bus Number */+	MV_U32			p2pSecLatencyTimer;	/* P2P Econdary Latency Timer*/+	MV_U32			p2pIObase;			/* P2P IO Base */+	MV_U32			p2pIOLimit;			/* P2P IO Linit */+	MV_BOOL			bIO32;	+	MV_U32			p2pSecStatus;		/* P2P Secondary Status */+	MV_U32			p2pMemBase;			/* P2P Memory Space */+	MV_U32			p2pMemLimit;		/* P2P Memory Limit*/+	MV_U32			p2pPrefMemBase;		/* P2P Prefetchable Mem Base*/+	MV_U32			p2pPrefMemLimit;	/* P2P Prefetchable Memory Limit*/+	MV_BOOL			bPrefMem64;	+	MV_U32			p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/+	MV_U32			p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/+++	MV_U32			pciCacheLine;		/* Pci agent cache line */+	MV_U32			pciLatencyTimer;	/* Pci agent Latency timer  */+    MV_PCI_HEADER	pciHeader;			/* Pci agent header type*/+    MV_BOOL			isMultiFunction;	/* Multi function support */+	MV_BOOL			isBISTCapable;		/* Self test capable */++	MV_U32			subSysID;			/* Sub System ID */+	MV_U32			subSysVenID;		/* Sub System Vendor ID */++	MV_BOOL			isExpRom;			/* Expantion Rom support */+	MV_U32			expRomAddr;			/* Expantion Rom pointer */++	MV_U32			capListPointer;		/* Capability list pointer */++	MV_U32			irqLine;		/* IRQ line  */+	MV_PCI_INT_PIN	intPin;			/* Interrupt pin */+	MV_U32			minGrant;		/* Minimum grant*/+	MV_U32			maxLatency;		/* Maximum latency*/++	MV_U32 			funtionsNum;	/* pci agent total functions number */++	MV_U32 			barsNum;+    MV_U8           type[60];		/* class name of the pci agent */+++} MV_PCI_DEVICE;++/* PCI gloabl functions */+MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);+++/* Performs a full scan on both PCIs and returns all possible details on the+   agents found on the bus. */+MV_STATUS mvPciScan(MV_U32 pciIf,+					MV_PCI_DEVICE *pPciAgents,+					MV_U32 *pPciAgentsNum);+++#endif /* #ifndef __INCmvPciUtilsh */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c	2010-11-09 20:28:11.702495387 +0100@@ -0,0 +1,1143 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "pex/mvPex.h"++#include "ctrlEnv/mvCtrlEnvLib.h"++/* defines  */       +#ifdef MV_DEBUG         +#define DB(x)	x+#else                +#define DB(x)    +#endif	             ++MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)+{+	MV_PEX_MODE pexMode;+	MV_U32 regVal;+	MV_U32	status;+ +    /* First implement Guideline (GL# PCI Express-2) Wrong Default Value    */+    /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */+    /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L      */+ +    if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&+	(mvCtrlModelGet() != MV_6281_DEV_ID) &&+	(mvCtrlModelGet() != MV_6192_DEV_ID) &&+    (mvCtrlModelGet() != MV_6190_DEV_ID) &&+	(mvCtrlModelGet() != MV_6180_DEV_ID) &&+        	(mvCtrlModelGet() != MV_6183_DEV_ID) &&+	(mvCtrlModelGet() != MV_6183L_DEV_ID) &&+        	(mvCtrlModelGet() != MV_78100_DEV_ID) &&+        	(mvCtrlModelGet() != MV_78200_DEV_ID) &&+	(mvCtrlModelGet() != MV_76100_DEV_ID) &&+	(mvCtrlModelGet() != MV_78XX0_DEV_ID))+    {++        /* Read current value of TXAMP */+        MV_REG_WRITE(0x41b00, 0x80820000);   /* Write the read command   */++        regVal = MV_REG_READ(0x41b00);      /* Extract the data         */++        /* Prepare new data for write */+        regVal &= ~0x7;                     /* Clear bits [2:0]         */+        regVal |=  0x4;                     /* Set the new value        */+        regVal &= ~0x80000000;              /* Set "write" command      */+        MV_REG_WRITE(0x41b00, regVal);      /* Write the write command  */++    }+    else+    {+        /* Implement 1.0V termination GL for 88F1281 device only */+        /* BIT0 - Common mode feedback */+        /* BIT3 - TxBuf, extra drive for 1.0V termination */+        if (mvCtrlModelGet() == MV_1281_DEV_ID)+        {+                MV_REG_WRITE(0x41b00, 0x80860000);   /* Write the read command   */+                regVal = MV_REG_READ(0x41b00);      /* Extract the data         */+                regVal |= (BIT0 | BIT3);+                regVal &= ~0x80000000;              /* Set "write" command      */+                MV_REG_WRITE(0x41b00, regVal);      /* Write the write command  */++                MV_REG_WRITE(0x31b00, 0x80860000);   /* Write the read command   */+                regVal = MV_REG_READ(0x31b00);      /* Extract the data         */+                regVal |= (BIT0 | BIT3);+                regVal &= ~0x80000000;              /* Set "write" command      */+                MV_REG_WRITE(0x31b00, regVal);      /* Write the write command  */+        }+    }++        if( mvPexModeGet(pexIf, &pexMode) != MV_OK)+        {+                mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);+                return MV_ERROR;+        }++        /* Check that required PEX type is the one set in reset time */+        if (pexType != pexMode.pexType)+        {+                /* No Link. Shut down the Phy */+		mvPexPowerDown(pexIf);+                mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);+                return MV_ERROR;+        }++        if (MV_PEX_ROOT_COMPLEX == pexType)+        {+                mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));+                mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));+        +                /* Local device master Enable */+                mvPexMasterEnable(pexIf, MV_TRUE);+        +                /* Local device slave Enable */+                mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),+                                                 mvPexLocalDevNumGet(pexIf), MV_TRUE);+		/* Interrupt disable */+		status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));+		status |= PXSAC_INT_DIS;+		MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);+        }++        /* now wait 500 ms to be sure the link is valid (spec compliant) */ +        mvOsDelay(500);+	/* Check if we have link */+	if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)+	{+		mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);+		return MV_NO_SUCH;+	}++	if (MV_PEX_WITDH_X1 ==  pexMode.pexWidth)+	{+		mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);+	}+	else+	{+		mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);+	}++#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT+	mvPexVrtBrgInit(pexIf);+#endif+	return MV_OK;+}++/*******************************************************************************+* mvPexModeGet - Get Pex Mode+*+* DESCRIPTION:+*+* INPUT:+*       pexIf   - PEX interface number.+*+* OUTPUT:+*       pexMode - Pex mode structure+*+* RETURN:+*       MV_OK on success , MV_ERROR otherwise+*+*******************************************************************************/+MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)+{+	MV_U32 pexData;++	/* Parameter checking   */+	if (PEX_DEFAULT_IF != pexIf)+	{+		if (pexIf >= mvCtrlPexMaxIfGet())+		{+			mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);+			return MV_ERROR;+		}+	}++	pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));++	switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)+	{+	case PXCR_DEV_TYPE_CTRL_CMPLX:+		pexMode->pexType = MV_PEX_ROOT_COMPLEX;+		break;+	case PXCR_DEV_TYPE_CTRL_POINT:+		pexMode->pexType = MV_PEX_END_POINT;+		break;++	}++    /* Check if we have link */+    if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)+    {+        pexMode->pexLinkUp = MV_FALSE;+        +        /* If there is no link, the auto negotiation data is worthless */+        pexMode->pexWidth  = MV_PEX_WITDH_INVALID;+    }   +    else+    {+        pexMode->pexLinkUp = MV_TRUE;++        /* We have link. The link width is now valid */+        pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));+        pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >> +                             PXLCSR_NEG_LNK_WDTH_OFFS);+    }++    return MV_OK;+}+++/* PEX configuration space read write */++/*******************************************************************************+* mvPexConfigRead - Read from configuration space+*+* DESCRIPTION:+*       This function performs a 32 bit read from PEX configuration space.+*       It supports both type 0 and type 1 of Configuration Transactions +*       (local and over bridge). In order to read from local bus segment, use +*       bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers +*       will result configuration transaction of type 1 (over bridge).+*+* INPUT:+*       pexIf   - PEX interface number.+*       bus     - PEX segment bus number.+*       dev     - PEX device number.+*       func    - Function number.+*       regOffs - Register offset.       +*+* OUTPUT:+*       None.+*+* RETURN:+*       32bit register data, 0xffffffff on error+*+*******************************************************************************/+MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func, +                        MV_U32 regOff)+{+#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)+        return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);+}++MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,+                        MV_U32 regOff)+{+#endif+	MV_U32 pexData = 0;+	MV_U32	localDev,localBus;++	/* Parameter checking   */+	if (PEX_DEFAULT_IF != pexIf)+	{+		if (pexIf >= mvCtrlPexMaxIfGet())+		{+			mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);+			return 0xFFFFFFFF;+		}+	}++	if (dev >= MAX_PEX_DEVICES)+	{+		DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));+		return 0xFFFFFFFF;+	}+	+	if (func >= MAX_PEX_FUNCS)+	{+		DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));+		return 0xFFFFFFFF;+	}+	+	if (bus >= MAX_PEX_BUSSES)+	{+		DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));+		return MV_ERROR;+	}+    	     +    DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",+                   pexIf, bus, dev, func, regOff));+	+	localDev = mvPexLocalDevNumGet(pexIf);+	localBus = mvPexLocalBusNumGet(pexIf);+                                     +    /* Speed up the process. In case on no link, return MV_ERROR */+    if ((dev != localDev) || (bus != localBus))+    {+        pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));++        if ((pexData & PXSR_DL_DOWN))+        {+            return MV_ERROR;+        }+    }++    /* in PCI Express we have only one device number */+	/* and this number is the first number we encounter +	else that the localDev*/+	/* spec pex define return on config read/write on any device */+	if (bus == localBus)+	{+		if (localDev == 0)+		{+			/* if local dev is 0 then the first number we encounter +			after 0 is 1 */+			if ((dev != 1)&&(dev != localDev))+			{+				return MV_ERROR;+			}	+		}+		else+		{+			/* if local dev is not 0 then the first number we encounter +			is 0 */+	+			if ((dev != 0)&&(dev != localDev))+			{+				return MV_ERROR;+			}+		}+		if(func != 0 ) /* i.e bridge */+		{+			return MV_ERROR;+		}+	}+    +    +	/* Creating PEX address to be passed */+	pexData = (bus << PXCAR_BUS_NUM_OFFS);+	pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);+	pexData |= (func << PXCAR_FUNC_NUM_OFFS);+	pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */+	/* extended register space */+	pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> +				PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);++	pexData |= PXCAR_CONFIG_EN; +	+	/* Write the address to the PEX configuration address register */+	MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);++	DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));+    +	+	/* In order to let the PEX controller absorbed the address of the read 	*/+	/* transaction we perform a validity check that the address was written */+	if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))+	{+		return MV_ERROR;+	}++	/* cleaning Master Abort */+	MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND), +				   PXSAC_MABORT);+#if 0+	/* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration   */+	/* This guideline is relevant for all devices except of the following devices:+	   88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above+	   88F6183 A0 and above, 88F6183L  */+	if ( ( (dev != localDev) || (bus != localBus) ) && +		(+		!(MV_5281_DEV_ID == mvCtrlModelGet())&&+		!((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&+		!(MV_1281_DEV_ID == mvCtrlModelGet())&&+		!(MV_6183_DEV_ID == mvCtrlModelGet())&&+		!(MV_6183L_DEV_ID == mvCtrlModelGet())&&+		!(MV_6281_DEV_ID == mvCtrlModelGet())&&+		!(MV_6192_DEV_ID == mvCtrlModelGet())&&+		!(MV_6190_DEV_ID == mvCtrlModelGet())&&+        !(MV_6180_DEV_ID == mvCtrlModelGet())&& +		!(MV_78XX0_DEV_ID == mvCtrlModelGet()) +		))+	{++		/* PCI-Express configuration read work-around */++		/* we will use one of the Punit (AHBToMbus) windows to access the xbar +		and read the data from there */+		/*+		Need to configure the 2 free Punit (AHB to MBus bridge) +		address decoding windows:+		Configure the flash Window to handle Configuration space requests +		for PEX0/1:+		1.    write 0x7931/0x7941 to the flash window and the size, +		      79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn+		2.    write base to flash window +		+		Configuration transactions from the CPU should write/read the data +		to/from address of the form:+		addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)+		addr[27:24] = extended register number+		addr[23:16] = bus number+		addr[15:11] = device number+		addr[10:8]   = function number+		addr[7:0]     = register number+		*/++		#include "ctrlEnv/sys/mvAhbToMbus.h"+		{+			MV_U32 winNum;+			MV_AHB_TO_MBUS_DEC_WIN originWin;+			MV_U32 pciAddr=0;+			MV_U32 remapLow=0,remapHigh=0;++			/* +			We will use DEV_CS2\Flash window for this workarround +			*/+            +			winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);++			/* save remap values if exist */+			if ((1 == winNum)||(0 == winNum))+			{+				remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));+				remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));++			}+			++			/* save the original window values */+			mvAhbToMbusWinGet(winNum,&originWin);++			if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)+			{+				/* set the window as xbar window */+				if (pexIf)+				{+					MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), +					(0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));+				}+				else+				{+					MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), +					(0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));+				}++				MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),+							 originWin.addrWin.baseLow);++				/*pciAddr = originWin.addrWin.baseLow;*/+				pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(+					(MV_U32)originWin.addrWin.baseLow);+			+			}+			else+			{+				/* set the window as xbar window */+				if (pexIf)+				{+					MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), +					(0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));+				}+				else+				{+					MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), +					(0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));+				}++				MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),+							 PEX_CONFIG_RW_WA_BASE);++				pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);+			}+			+			+			/* remap should be as base */+			if ((1 == winNum)||(0 == winNum))+			{+			   MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);+			   MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);++			}++			/* extended register space */+			pciAddr |= (bus << 16);+			pciAddr |= (dev << 11);+			pciAddr |= (func << 8);+			pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */++			pexData = *(MV_U32*)pciAddr; +			pexData = MV_32BIT_LE(pexData); /* Data always in LE */++			/* restore the original window values */+			mvAhbToMbusWinSet(winNum,&originWin);++			/* restore original remap values*/+			if ((1 == winNum)||(0 == winNum))+			{+			   MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);+			   MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);++			}+		}+	}+	else+#endif+	{+		/* Read the Data returned in the PEX Data register */+		pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));++	}++	DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));+	+	return pexData;++}++/*******************************************************************************+* mvPexConfigWrite - Write to configuration space+*+* DESCRIPTION:+*       This function performs a 32 bit write to PEX configuration space.+*       It supports both type 0 and type 1 of Configuration Transactions +*       (local and over bridge). In order to write to local bus segment, use +*       bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers +*       will result configuration transaction of type 1 (over bridge).+*+* INPUT:+*       pexIf   - PEX interface number.+*       bus     - PEX segment bus number.+*       dev     - PEX device number.+*       func    - Function number.+*       regOffs - Register offset.       +*       data    - 32bit data.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev, +                           MV_U32 func, MV_U32 regOff, MV_U32 data)+{+#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)+        return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);+}++MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,+                           MV_U32 func, MV_U32 regOff, MV_U32 data)+{+#endif+	MV_U32 pexData = 0;+	MV_U32	localDev,localBus;++	/* Parameter checking   */+	if (PEX_DEFAULT_IF != pexIf)+	{+		if (pexIf >= mvCtrlPexMaxIfGet())+		{+			mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n", +																		pexIf);+			return MV_ERROR;+		}+	}++	if (dev >= MAX_PEX_DEVICES)+	{+		mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);+		return MV_BAD_PARAM;+	}++	if (func >= MAX_PEX_FUNCS)+	{+		mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);+		return MV_ERROR;+	}++	if (bus >= MAX_PEX_BUSSES)+	{+		mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);+		return MV_ERROR;+	}++++	localDev = mvPexLocalDevNumGet(pexIf);+	localBus = mvPexLocalBusNumGet(pexIf);++	+	/* in PCI Express we have only one device number other than ourselves*/+	/* and this number is the first number we encounter +		else than the localDev that can be any valid dev number*/+	/* pex spec define return on config read/write on any device */+	if (bus == localBus)+	{++		if (localDev == 0)+		{+			/* if local dev is 0 then the first number we encounter +			after 0 is 1 */+			if ((dev != 1)&&(dev != localDev))+			{+				return MV_ERROR;+			}+	+		}+		else+		{+			/* if local dev is not 0 then the first number we encounter +			is 0 */+	+			if ((dev != 0)&&(dev != localDev))+			{+				return MV_ERROR;+			}+		}++		+	}++	/* if we are not accessing ourselves , then check the link */+	if ((dev != localDev) || (bus != localBus) )+	{+		/* workarround */+		/* when no link return MV_ERROR */++		pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));++		if ((pexData & PXSR_DL_DOWN))+		{+			return MV_ERROR;+		}++	}++	pexData =0;++	/* Creating PEX address to be passed */+	pexData |= (bus << PXCAR_BUS_NUM_OFFS);+	pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);+	pexData |= (func << PXCAR_FUNC_NUM_OFFS);+	pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */+	/* extended register space */+	pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> +				PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);+	pexData |= PXCAR_CONFIG_EN; +	+	DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",+		   pexIf,bus,func,dev,regOff,data,pexData) ); ++	/* Write the address to the PEX configuration address register */+	MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);++	/* Clear CPU pipe. Important where CPU can perform OOO execution */+    	CPU_PIPE_FLUSH;++	/* In order to let the PEX controller absorbed the address of the read 	*/+	/* transaction we perform a validity check that the address was written */+	if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))+	{+		return MV_ERROR;+	}++	/* Write the Data passed to the PEX Data register */+	MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);++	return MV_OK;++}++/*******************************************************************************+* mvPexMasterEnable - Enable/disale PEX interface master transactions.+*+* DESCRIPTION:+*       This function performs read modified write to PEX command status +*       (offset 0x4) to set/reset bit 2. After this bit is set, the PEX +*       master is allowed to gain ownership on the bus, otherwise it is +*       incapable to do so.+*+* INPUT:+*       pexIf  - PEX interface number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)+{+	MV_U32 pexCommandStatus;+	MV_U32 localBus;+	MV_U32 localDev;++	/* Parameter checking   */+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_ERROR;+	}++	localBus = mvPexLocalBusNumGet(pexIf);+	localDev = mvPexLocalDevNumGet(pexIf);+	+	pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,+							    PEX_STATUS_AND_COMMAND));+++	if (MV_TRUE == enable)+	{+		pexCommandStatus |= PXSAC_MASTER_EN;+	}+	else+	{+		pexCommandStatus &= ~PXSAC_MASTER_EN;+	}++	+	MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),+				 pexCommandStatus);++	return MV_OK;+}+++/*******************************************************************************+* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.+*+* DESCRIPTION:+*       This function performs read modified write to PEX command status +*       (offset 0x4) to set/reset bit 0 and 1. After those bits are set, +*       the PEX slave is allowed to respond to PEX IO space access (bit 0) +*       and PEX memory space access (bit 1). +*+* INPUT:+*       pexIf  - PEX interface number.+*       dev     - PEX device number.+*       enable - Enable/disable parameter.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)+{+	MV_U32 pexCommandStatus;+	MV_U32 RegOffs;++	/* Parameter checking   */+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}+	if (dev >= MAX_PEX_DEVICES)+	{+		mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);+		return MV_BAD_PARAM;++	}++	+	RegOffs = PEX_STATUS_AND_COMMAND;+	+	pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);++    if (MV_TRUE == enable)+	{+		pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);+	}+	else                             +	{+		pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);+	}++	mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);++	return MV_OK;++}++/*******************************************************************************+* mvPexLocalBusNumSet - Set PEX interface local bus number.+*+* DESCRIPTION:+*       This function sets given PEX interface its local bus number.+*       Note: In case the PEX interface is PEX-X, the information is read-only.+*+* INPUT:+*       pexIf  - PEX interface number.+*       busNum - Bus number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_NOT_ALLOWED in case PEX interface is PEX-X. +*		MV_BAD_PARAM on bad parameters ,+*       otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)+{+	MV_U32 pexStatus;+	MV_U32 localBus;+	MV_U32 localDev;+++	/* Parameter checking   */+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);+		return MV_BAD_PARAM;+	}+	if (busNum >= MAX_PEX_BUSSES)+	{+		mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);+		return MV_ERROR;++	}++	localBus = mvPexLocalBusNumGet(pexIf);+	localDev = mvPexLocalDevNumGet(pexIf);++++	pexStatus  = MV_REG_READ(PEX_STATUS_REG(pexIf));++	pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;++	pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;++	MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);+++	return MV_OK;+}+++/*******************************************************************************+* mvPexLocalBusNumGet - Get PEX interface local bus number.+*+* DESCRIPTION:+*       This function gets the local bus number of a given PEX interface.+*+* INPUT:+*       pexIf  - PEX interface number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Local bus number.0xffffffff on Error+*+*******************************************************************************/+MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)+{+	MV_U32 pexStatus;++	/* Parameter checking   */+	if (PEX_DEFAULT_IF != pexIf)+	{+		if (pexIf >= mvCtrlPexMaxIfGet())+		{+			mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);+			return 0xFFFFFFFF;+		}+	}+++	pexStatus  = MV_REG_READ(PEX_STATUS_REG(pexIf));++	pexStatus &= PXSR_PEX_BUS_NUM_MASK;++	return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);++}+++/*******************************************************************************+* mvPexLocalDevNumSet - Set PEX interface local device number.+*+* DESCRIPTION:+*       This function sets given PEX interface its local device number.+*       Note: In case the PEX interface is PEX-X, the information is read-only.+*+* INPUT:+*       pexIf  - PEX interface number.+*       devNum - Device number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_NOT_ALLOWED in case PEX interface is PEX-X. +*		MV_BAD_PARAM on bad parameters ,+*       otherwise MV_OK+*+*******************************************************************************/+MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)+{+	MV_U32 pexStatus;+	MV_U32 localBus;+	MV_U32 localDev;++	/* Parameter checking   */+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);+		return MV_BAD_PARAM;+	}+	if (devNum >= MAX_PEX_DEVICES)+	{+		mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", +																	   devNum);+		return MV_BAD_PARAM;++	}+	+	localBus = mvPexLocalBusNumGet(pexIf);+	localDev = mvPexLocalDevNumGet(pexIf);+++	pexStatus  = MV_REG_READ(PEX_STATUS_REG(pexIf));++	pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;++	pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;++	MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);+++	return MV_OK;+}++/*******************************************************************************+* mvPexLocalDevNumGet - Get PEX interface local device number.+*+* DESCRIPTION:+*       This function gets the local device number of a given PEX interface.+*+* INPUT:+*       pexIf  - PEX interface number.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Local device number. 0xffffffff on Error+*+*******************************************************************************/+MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)+{+	MV_U32 pexStatus;++	/* Parameter checking   */+	+	if (PEX_DEFAULT_IF != pexIf)+	{+		if (pexIf >= mvCtrlPexMaxIfGet())+		{+			mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n", +																   		pexIf);+			return 0xFFFFFFFF;+		}+	}+	+	pexStatus  = MV_REG_READ(PEX_STATUS_REG(pexIf));++	pexStatus &= PXSR_PEX_DEV_NUM_MASK;++	return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);+}++MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)+{++	MV_U32 regAddr;+	if (pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);+		return;+	}+	regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));+	MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);+	*value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf)); +}+++MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)+{++	MV_U32 regAddr;+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);+		return;+	}+	regAddr = (((regOffset & 0x3fff) << 16) | value);+	MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);+}++/*******************************************************************************+* mvPexActiveStateLinkPMEnable+*+* DESCRIPTION:+*       Enable Active Link State Power Management+*+* INPUT:+*       pexIf   - PEX interface number.+*	enable	- MV_TRUE to enable ASPM, MV_FALSE to disable.+*+* OUTPUT:+*       None+*+* RETURN:+*       MV_OK on success , MV_ERROR otherwise+*+*******************************************************************************/+MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)+{+	MV_U32 reg;++	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_ERROR;+	}++	reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;+	if(enable == MV_TRUE)+		reg |= PXPMER_L1_ASPM_EN_MASK;+	MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);++	/* Enable / Disable L0/1 entry */ +	reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))+			& ~PXLCSR_ASPM_CNT_MASK;+	if(enable == MV_TRUE)+		reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;+	MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);++	return MV_OK;+}+++/*******************************************************************************+* mvPexForceX1+*+* DESCRIPTION:+*       shut down lanes 1-3 if recognize that attached to an x1 end-point+* INPUT:+*       pexIf   - PEX interface number.+*+* OUTPUT:+*       None+*+* RETURN:+*       MV_OK on success , MV_ERROR otherwise+*+*******************************************************************************/+MV_U32 mvPexForceX1(MV_U32 pexIf)+{+	MV_U32 regData = 0;+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_BAD_PARAM;+	}++	regData  = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;+	regData |= PXCR_CONF_LINK_X1;++	MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);+	return MV_OK;+}++MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)+{+	if(pexIf >= mvCtrlPexMaxIfGet())+	{+		mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);+		return MV_FALSE;+	}+	return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);	+}+++MV_VOID mvPexPowerDown(MV_U32 pexIf)+{+	if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||+		(mvCtrlModelGet() == MV_76100_DEV_ID) ||+		(mvCtrlModelGet() == MV_78100_DEV_ID) ||+		(mvCtrlModelGet() == MV_78200_DEV_ID) )+	{+		mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);	+	}+	else+	{+		MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);+	}+}+++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h	2010-11-09 20:28:11.742495415 +0100@@ -0,0 +1,168 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCPEXH+#define __INCPEXH++#include "mvCommon.h"+#include "mvOs.h"+#include "pex/mvPexRegs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"++++/* NOTE not supported in this driver:*/+  ++/* defines */+/* The number of supported PEX interfaces depend on Marvell controller 		*/+/* device number. This device number ID is located on the PEX unit 			*/+/* configuration header. This creates a loop where calling PEX 				*/+/* configuration read/write	routine results a call to get PEX configuration */+/* information etc. This macro defines a default PEX interface. This PEX	*/+/* interface is sure to exist.												*/+#define PEX_DEFAULT_IF	0+++/* typedefs */+/* The Marvell controller supports both root complex and end point devices */+/* This enumeration describes the PEX type.                                 */+typedef enum _mvPexType+{+    MV_PEX_ROOT_COMPLEX,   	/* root complex device */+    MV_PEX_END_POINT        /* end point device */+}MV_PEX_TYPE;++typedef enum _mvPexWidth+{+    MV_PEX_WITDH_X1 = 1,+    MV_PEX_WITDH_X2,+    MV_PEX_WITDH_X3,+    MV_PEX_WITDH_X4,+    MV_PEX_WITDH_INVALID+}MV_PEX_WIDTH;++/* PEX Bar attributes */+typedef struct _mvPexMode+{+	MV_PEX_TYPE 	pexType;+	MV_PEX_WIDTH    pexWidth;+	MV_BOOL         pexLinkUp;+}MV_PEX_MODE;++++/* Global Functions prototypes */+/* mvPexInit - Initialize PEX interfaces*/+MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);++/* mvPexModeGet - Get Pex If mode */+MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);++/* mvPexConfigRead - Read from configuration space */+MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,+						MV_U32 func,MV_U32 regOff);++/* mvPexConfigWrite - Write to configuration space */+MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,+                           MV_U32 func, MV_U32 regOff, MV_U32 data);++/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/+MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);++/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/+MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);++/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/+MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);++/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/+MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);++/* mvPexLocalDevNumSet - Set PEX interface local device number.*/+MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);++/* mvPexLocalDevNumGet - Get PEX interface local device number.*/+MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);+/* mvPexForceX1 - Force PEX interface to X1 mode. */+MV_U32 mvPexForceX1(MV_U32 pexIf);++/* mvPexIsPowerUp - Is PEX interface Power up? */+MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);++/* mvPexPowerDown - Power Down */+MV_VOID mvPexPowerDown(MV_U32 pexIf);++/* mvPexPowerUp - Power Up */+MV_VOID mvPexPowerUp(MV_U32 pexIf);++/* mvPexPhyRegRead - Pex phy read */+MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);++/* mvPexPhyRegWrite - Pex phy write */+MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);++MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);++#endif /* #ifndef __INCPEXH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h	2010-11-09 20:28:11.782495900 +0100@@ -0,0 +1,751 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCPEXREGSH+#define __INCPEXREGSH++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* defines */+#define MAX_PEX_DEVICES         32+#define MAX_PEX_FUNCS           8+#define MAX_PEX_BUSSES          256++++/*********************************************************/+/* PCI Express Configuration Cycles Generation Registers */+/*********************************************************/++#define PEX_CFG_ADDR_REG(pexIf)		((PEX_IF_BASE(pexIf)) + 0x18F8)+#define PEX_CFG_DATA_REG(pexIf)		((PEX_IF_BASE(pexIf)) + 0x18FC)+#define PEX_PHY_ACCESS_REG(pexIf)	((PEX_IF_BASE(pexIf)) + 0x1B00)+/* PCI Express Configuration Address Register */+/* PEX_CFG_ADDR_REG (PXCAR)*/++#define PXCAR_REG_NUM_OFFS			2+#define PXCAR_REG_NUM_MAX			0x3F+#define PXCAR_REG_NUM_MASK			(PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)+#define PXCAR_FUNC_NUM_OFFS			8+#define PXCAR_FUNC_NUM_MAX			0x7+#define PXCAR_FUNC_NUM_MASK			(PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)+#define PXCAR_DEVICE_NUM_OFFS		11+#define PXCAR_DEVICE_NUM_MAX		0x1F+#define PXCAR_DEVICE_NUM_MASK		(PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)+#define PXCAR_BUS_NUM_OFFS			16+#define PXCAR_BUS_NUM_MAX			0xFF+#define PXCAR_BUS_NUM_MASK			(PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)+#define PXCAR_EXT_REG_NUM_OFFS		24+#define PXCAR_EXT_REG_NUM_MAX		0xF++/* in pci express register address is now the legacy register address (8 bits)+with the new extended register address (more 4 bits) , below is the mask of+the upper 4 bits of the full register address */++#define PXCAR_REAL_EXT_REG_NUM_OFFS	8+#define PXCAR_EXT_REG_NUM_MASK		(PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)+#define PXCAR_CONFIG_EN				BIT31++#define PXCAR_REAL_EXT_REG_NUM_OFFS     8+#define PXCAR_REAL_EXT_REG_NUM_MASK     (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)++/* The traditional PCI spec defined 6-bit field to describe register offset.*/ +/* The new PCI Express extend the register offset by an extra 4-bits.       */+/* The below macro assign 10-bit register offset into the apprpreate        */+/* fields in the CFG_ADDR_REG                                               */+#define PXCAR_REG_OFFS_SET(regOffs)                         \+ ( (regOff & PXCAR_REG_NUM_MASK) | \+   ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )++/***********************************/+/* PCI Express Interrupt registers */+/***********************************/+#define PEX_CAUSE_REG(pexIf)		((PEX_IF_BASE(pexIf)) + 0x1900)+#define PEX_MASK_REG(pexIf)		((PEX_IF_BASE(pexIf)) + 0x1910)++#define PXICR_TX_REQ_IN_DLDOWN_ERR  BIT0  /* Transmit request while field   */+                                          /* <DLDown> of the PCI Express    */+/* PCI Express Interrupt Cause */+/* PEX_INT_CAUSE_REG  (PXICR)*/+/* PEX_INT_MASK_REG*/+/*+NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets+upon an error event occurrence. A write of 0 clears the bit. A write of 1 has+no affect. Bits[24:27} are set and cleared upon reception of interrupt+emulation messages.++Mask bit per cause bit. If a bit is set to 1, the corresponding event is+enabled. Mask does not affect setting of the Interrupt Cause register bits;+it only affects the assertion of the interrupt .*/+                                          ++#define PXICR_MDIS_CAUSE			BIT1  /* Attempt to generate PCI transaction +                                             while master is disabled */+#define PXICR_ERR_WRTO_REG_CAUSE	BIT3  /* Erroneous write attempt to+                                             PCI Express internal register*/+#define PXICR_HIT_DFLT_WIN_ERR		BIT4  /* Hit Default Window Error */+#define PXICR_RX_RAM_PAR_ERR        BIT6  /* Rx RAM Parity Error */+#define PXICR_TX_RAM_PAR_ERR        BIT7  /* Tx RAM Parity Error */+#define PXICR_COR_ERR_DET			BIT8  /* Correctable Error Detected*/+#define PXICR_NF_ERR_DET			BIT9  /* Non-Fatal Error Detected*/+#define PXICR_FERR_DET				BIT10 /* Fatal Error Detected*/+#define PXICR_DSTATE_CHANGE			BIT11 /* Dstate Change Indication*/+#define PXICR_BIST					BIT12 /* PCI-Express BIST activated*/+#define PXICR_FLW_CTRL_PROT     BIT14 /* Flow Control Protocol Error */++#define PXICR_RCV_UR_CA_ERR         BIT15 /* Received UR or CA status. */+#define PXICR_RCV_ERR_FATAL			BIT16 /* Received ERR_FATAL message.*/+#define PXICR_RCV_ERR_NON_FATAL		BIT17 /* Received ERR_NONFATAL message*/+#define PXICR_RCV_ERR_COR			BIT18 /* Received ERR_COR message.*/+#define PXICR_RCV_CRS				BIT19 /* Received CRS completion status*/+#define PXICR_SLV_HOT_RESET			BIT20 /* Received Hot Reset Indication*/+#define PXICR_SLV_DIS_LINK			BIT21 /* Slave Disable Link Indication*/+#define PXICR_SLV_LB				BIT22 /* Slave Loopback Indication*/+#define PXICR_LINK_FAIL				BIT23 /* Link Failure indication.*/+#define PXICR_RCV_INTA				BIT24 /* IntA status.*/+#define PXICR_RCV_INTB				BIT25 /* IntB status.*/+#define PXICR_RCV_INTC				BIT26 /* IntC status.*/+#define PXICR_RCV_INTD				BIT27 /* IntD status.*/+#define PXICR_RCV_PM_PME            BIT28 /* Received PM_PME message. */+++/********************************************/+/* PCI Express Control and Status Registers */+/********************************************/+#define PEX_CTRL_REG(pexIf)				((PEX_IF_BASE(pexIf)) + 0x1A00)+#define PEX_STATUS_REG(pexIf)				((PEX_IF_BASE(pexIf)) + 0x1A04)+#define PEX_COMPLT_TMEOUT_REG(pexIf)			((PEX_IF_BASE(pexIf)) + 0x1A10)+#define PEX_PWR_MNG_EXT_REG(pexIf)			((PEX_IF_BASE(pexIf)) + 0x1A18)+#define PEX_FLOW_CTRL_REG(pexIf)			((PEX_IF_BASE(pexIf)) + 0x1A20)+#define PEX_ACK_TMR_4X_REG(pexIf)			((PEX_IF_BASE(pexIf)) + 0x1A30)+#define PEX_ACK_TMR_1X_REG(pexIf)			((PEX_IF_BASE(pexIf)) + 0x1A40)+#define PEX_TL_CTRL_REG(pexIf)				((PEX_IF_BASE(pexIf)) + 0x1AB0)+++#define PEX_RAM_PARITY_CTRL_REG(pexIf)  		((PEX_IF_BASE(pexIf)) + 0x1A50)+/* PCI Express Control Register */+/* PEX_CTRL_REG (PXCR) */++#define PXCR_CONF_LINK_OFFS             0+#define PXCR_CONF_LINK_MASK             (1 << PXCR_CONF_LINK_OFFS)+#define PXCR_CONF_LINK_X4               (0 << PXCR_CONF_LINK_OFFS)+#define PXCR_CONF_LINK_X1               (1 << PXCR_CONF_LINK_OFFS)+#define PXCR_DEV_TYPE_CTRL_OFFS			1     /*PCI ExpressDevice Type Control*/+#define PXCR_DEV_TYPE_CTRL_MASK			BIT1+#define PXCR_DEV_TYPE_CTRL_CMPLX		(1 << PXCR_DEV_TYPE_CTRL_OFFS)+#define PXCR_DEV_TYPE_CTRL_POINT		(0 << PXCR_DEV_TYPE_CTRL_OFFS)+#define PXCR_CFG_MAP_TO_MEM_EN			BIT2  /* Configuration Header Mapping +											   to Memory Space Enable         */++#define PXCR_CFG_MAP_TO_MEM_EN			BIT2 /* Configuration Header Mapping +											   to Memory Space Enable*/++#define PXCR_RSRV1_OFFS					5+#define PXCR_RSRV1_MASK					(0x7 << PXCR_RSRV1_OFFS)+#define PXCR_RSRV1_VAL					(0x0 << PXCR_RSRV1_OFFS)++#define PXCR_CONF_MAX_OUTSTND_OFFS		8 /*Maximum outstanding NP requests as a master*/+#define PXCR_CONF_MAX_OUTSTND_MASK		(0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)+++#define PXCR_CONF_NFTS_OFFS				16 /*number of FTS Ordered-Sets*/+#define PXCR_CONF_NFTS_MASK				(0xff << PXCR_CONF_NFTS_OFFS)++#define PXCR_CONF_MSTR_HOT_RESET		BIT24 /*Master Hot-Reset.*/+#define PXCR_CONF_MSTR_LB				BIT26 /* Master Loopback */+#define PXCR_CONF_MSTR_DIS_SCRMB		BIT27 /* Master Disable Scrambling*/+#define PXCR_CONF_DIRECT_DIS_SCRMB		BIT28 /* Direct Disable Scrambling*/++/* PCI Express Status Register */+/* PEX_STATUS_REG (PXSR) */++#define PXSR_DL_DOWN					BIT0 /* DL_Down indication.*/++#define PXSR_PEX_BUS_NUM_OFFS			8 /* Bus Number Indication */+#define PXSR_PEX_BUS_NUM_MASK			(0xff << PXSR_PEX_BUS_NUM_OFFS)++#define PXSR_PEX_DEV_NUM_OFFS			16 /* Device Number Indication */+#define PXSR_PEX_DEV_NUM_MASK			(0x1f << PXSR_PEX_DEV_NUM_OFFS)++#define PXSR_PEX_SLV_HOT_RESET			BIT24 /* Slave Hot Reset Indication*/+#define PXSR_PEX_SLV_DIS_LINK			BIT25 /* Slave Disable Link Indication*/+#define PXSR_PEX_SLV_LB					BIT26 /* Slave Loopback Indication*/+#define PXSR_PEX_SLV_DIS_SCRMB			BIT27 /* Slave Disable Scrambling Indication*/+++/* PCI Express Completion Timeout Register */+/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/++#define PXCTR_CMP_TO_THRSHLD_OFFS		0 /* Completion Timeout Threshold */+#define PXCTR_CMP_TO_THRSHLD_MASK		(0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)++/* PCI Express Power Management Extended Register */+/* PEX_PWR_MNG_EXT_REG (PXPMER) */++#define PXPMER_L1_ASPM_EN_OFFS			1+#define PXPMER_L1_ASPM_EN_MASK			(0x1 << PXPMER_L1_ASPM_EN_OFFS)++/* PCI Express Flow Control Register */+/* PEX_FLOW_CTRL_REG (PXFCR)*/++#define PXFCR_PH_INIT_FC_OFFS			0 /*Posted Headers Flow Control Credit+										    Initial Value.*/+#define PXFCR_PH_INIT_FC_MASK			(0xff << PXFCR_PH_INIT_FC_OFFS)+++#define PXFCR_NPH_INIT_FC_OFFS			8 /* Classified Non-Posted Headers+											 Flow Control Credit Initial Value*/+#define PXFCR_NPH_INIT_FC_MASK			(0xff << PXFCR_NPH_INIT_FC_OFFS)++#define PXFCR_CH_INIT_FC_OFFS			16 /* Completion Headers Flow Control+											  Credit Initial Value Infinite*/+										+#define PXFCR_CH_INIT_FC_MASK			(0xff << PXFCR_CH_INIT_FC_OFFS)++#define PXFCR_FC_UPDATE_TO_OFFS			24 /* Flow Control Update Timeout */+#define PXFCR_FC_UPDATE_TO_MASK			(0xff << PXFCR_FC_UPDATE_TO_OFFS)++/* PCI Express Acknowledge Timers (4X) Register */+/* PEX_ACK_TMR_4X_REG (PXAT4R) */+#define PXAT1R_ACK_LAT_TOX4_OFFS		0  /* Ack Latency Timer Timeout Value */+#define PXAT1R_ACK_LAT_TOX4_MASK		(0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)+#define PXAT1R_ACK_RPLY_TOX4_OFFS		16 /* Ack Replay Timer Timeout Value  */+#define PXAT1R_ACK_RPLY_TOX4_MASK		(0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)++/* PCI Express Acknowledge Timers (1X) Register */+/* PEX_ACK_TMR_1X_REG (PXAT1R) */++#define PXAT1R_ACK_LAT_TOX1_OFFS		0 /* Acknowledge Latency Timer Timeout+										     Value for 1X Link*/+#define PXAT1R_ACK_LAT_TOX1_MASK		(0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)++#define PXAT1R_ACK_RPLY_TOX1_OFFS		16 /* Acknowledge Replay Timer Timeout+											  Value for 1X*/+#define PXAT1R_ACK_RPLY_TOX1_MASK		(0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)+++/* PCI Express TL Control Register */+/* PEX_TL_CTRL_REG (PXTCR) */++#define PXTCR_TX_CMP_BUFF_NO_OFFS		8 /*Number of completion buffers in Tx*/+#define PXTCR_TX_CMP_BUFF_NO_MASK		(0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)++/* PCI Express Debug MAC Control Register */+/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */++#define PXDMCR_LINKUP					BIT4++++/**********************************************/+/* PCI Express Configuration Header Registers */+/**********************************************/+#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg)	((PEX_IF_BASE(pexIf)) + (cfgReg))++#define PEX_DEVICE_AND_VENDOR_ID					0x000+#define PEX_STATUS_AND_COMMAND						0x004+#define PEX_CLASS_CODE_AND_REVISION_ID			    0x008+#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE		0x00C+#define PEX_MEMORY_BAR_BASE_ADDR(barNum)		 	(0x010 + ((barNum) << 2))+#define PEX_MV_BAR_BASE(barNum)						(0x010 + (barNum) * 8)+#define PEX_MV_BAR_BASE_HIGH(barNum)				(0x014 + (barNum) * 8)+#define PEX_BAR0_INTER_REG							0x010+#define PEX_BAR0_INTER_REG_HIGH						0x014+#define PEX_BAR1_REG								0x018+#define PEX_BAR1_REG_HIGH							0x01C+#define PEX_BAR2_REG								0x020+#define PEX_BAR2_REG_HIGH							0x024++#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID			0x02C+#define PEX_EXPANSION_ROM_BASE_ADDR_REG				0x030+#define PEX_CAPABILTY_LIST_POINTER					0x034+#define PEX_INTERRUPT_PIN_AND_LINE					0x03C++/* capability list */+#define PEX_POWER_MNG_CAPABILITY		            0x040+#define PEX_POWER_MNG_STATUS_CONTROL		        0x044++#define PEX_MSI_MESSAGE_CONTROL						0x050+#define PEX_MSI_MESSAGE_ADDR		                0x054+#define PEX_MSI_MESSAGE_HIGH_ADDR		            0x058+#define PEX_MSI_MESSAGE_DATA		                0x05C++#define PEX_CAPABILITY_REG							0x60+#define PEX_DEV_CAPABILITY_REG						0x64+#define PEX_DEV_CTRL_STAT_REG						0x68+#define PEX_LINK_CAPABILITY_REG						0x6C+#define PEX_LINK_CTRL_STAT_REG						0x70++#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG				0x100+#define PEX_UNCORRECT_ERR_STAT_REG					0x104+#define PEX_UNCORRECT_ERR_MASK_REG					0x108+#define PEX_UNCORRECT_ERR_SERVITY_REG				0x10C+#define PEX_CORRECT_ERR_STAT_REG					0x110+#define PEX_CORRECT_ERR_MASK_REG					0x114+#define PEX_ADV_ERR_CAPABILITY_CTRL_REG				0x118+#define PEX_HDR_LOG_FIRST_DWORD_REG					0x11C+#define PEX_HDR_LOG_SECOND_DWORD_REG				0x120+#define PEX_HDR_LOG_THIRD_DWORD_REG					0x124+#define PEX_HDR_LOG_FOURTH_DWORD_REG				0x128++++/* PCI Express Device and Vendor ID Register*/+/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/++#define PXDAVI_VEN_ID_OFFS			0 	/* Vendor ID */+#define PXDAVI_VEN_ID_MASK			(0xffff << PXDAVI_VEN_ID_OFFS)++#define PXDAVI_DEV_ID_OFFS			16	/* Device ID */+#define PXDAVI_DEV_ID_MASK  		(0xffff << PXDAVI_DEV_ID_OFFS)+++/* PCI Express Command and Status Register*/+/*PEX_STATUS_AND_COMMAND (PXSAC)*/++#define PXSAC_IO_EN			BIT0 	/* IO Enable 							  */+#define PXSAC_MEM_EN		BIT1	/* Memory Enable 						  */+#define PXSAC_MASTER_EN		BIT2	/* Master Enable 						  */+#define PXSAC_PERR_EN		BIT6	/* Parity Errors Respond Enable 		  */+#define PXSAC_SERR_EN		BIT8	/* Ability to assert SERR# line			  */+#define PXSAC_INT_DIS		BIT10   /* Interrupt Disable 					  */+#define PXSAC_INT_STAT		BIT19   /* Interrupt Status 			*/+#define PXSAC_CAP_LIST		BIT20	/* Capability List Support 				  */+#define PXSAC_MAS_DATA_PERR	BIT24   /* Master Data Parity Error				  */+#define PXSAC_SLAVE_TABORT	BIT27	/* Signalled Target Abort 	*/+#define PXSAC_RT_ABORT		BIT28	/* Recieved Target Abort 	*/+#define PXSAC_MABORT			BIT29	/* Recieved Master Abort 	*/+#define PXSAC_SYSERR			BIT30	/* Signalled system error 	*/+#define PXSAC_DET_PARERR		BIT31	/* Detect Parity Error 		*/+++/* PCI Express Class Code and Revision ID Register*/+/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/       ++#define PXCCARI_REVID_OFFS		0		/* Revision ID */+#define PXCCARI_REVID_MASK		(0xff << PXCCARI_REVID_OFFS)++#define PXCCARI_FULL_CLASS_OFFS	8		/* Full Class Code */+#define PXCCARI_FULL_CLASS_MASK	(0xffffff << PXCCARI_FULL_CLASS_OFFS)++#define PXCCARI_PROGIF_OFFS		8		/* Prog .I/F*/+#define PXCCARI_PROGIF_MASK		(0xff << PXCCARI_PROGIF_OFFS)++#define PXCCARI_SUB_CLASS_OFFS	16		/* Sub Class*/+#define PXCCARI_SUB_CLASS_MASK	(0xff << PXCCARI_SUB_CLASS_OFFS)++#define PXCCARI_BASE_CLASS_OFFS	24		/* Base Class*/+#define PXCCARI_BASE_CLASS_MASK	(0xff << PXCCARI_BASE_CLASS_OFFS)+++/* PCI Express BIST, Header Type and Cache Line Size Register*/+/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/ ++#define PXBHTLTCL_CACHELINE_OFFS		0	/* Specifies the cache line size */+#define PXBHTLTCL_CACHELINE_MASK		(0xff << PXBHTLTCL_CACHELINE_OFFS)++#define PXBHTLTCL_HEADTYPE_FULL_OFFS	16	/* Full Header Type */+#define PXBHTLTCL_HEADTYPE_FULL_MASK	(0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)++#define PXBHTLTCL_MULTI_FUNC			BIT23	/* Multi/Single function */++#define PXBHTLTCL_HEADER_OFFS			16		/* Header type */+#define PXBHTLTCL_HEADER_MASK			(0x7f << PXBHTLTCL_HEADER_OFFS)+#define PXBHTLTCL_HEADER_STANDARD		(0x0 << PXBHTLTCL_HEADER_OFFS)+#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE	(0x1 << PXBHTLTCL_HEADER_OFFS)+++#define PXBHTLTCL_BISTCOMP_OFFS		24	/* BIST Completion Code */+#define PXBHTLTCL_BISTCOMP_MASK		(0xf << PXBHTLTCL_BISTCOMP_OFFS)++#define PXBHTLTCL_BISTACT			BIT30	/* BIST Activate bit */+#define PXBHTLTCL_BISTCAP			BIT31	/* BIST Capable Bit */+#define PXBHTLTCL_BISTCAP_OFFS		31	+#define PXBHTLTCL_BISTCAP_MASK		BIT31	+#define PXBHTLTCL_BISTCAP_VAL		0+++/* PCI Express Subsystem Device and Vendor ID */+/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/++#define PXSIASVI_VENID_OFFS	0	/* Subsystem Manufacturer Vendor ID Number */+#define PXSIASVI_VENID_MASK	(0xffff << PXSIASVI_VENID_OFFS)++#define PXSIASVI_DEVID_OFFS	16	/* Subsystem Device ID Number */+#define PXSIASVI_DEVID_MASK	(0xffff << PXSIASVI_DEVID_OFFS)+++/* PCI Express Capability List Pointer Register*/+/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/++#define PXCLP_CAPPTR_OFFS	0		/* Capability List Pointer */+#define PXCLP_CAPPTR_MASK	(0xff << PXCLP_CAPPTR_OFFS)++/* PCI Express Interrupt Pin and Line Register */+/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/++#define PXIPAL_INTLINE_OFFS	0	/* Interrupt line (IRQ) */+#define PXIPAL_INTLINE_MASK	(0xff << PXIPAL_INTLINE_OFFS)++#define PXIPAL_INTPIN_OFFS	8	/* interrupt pin (A,B,C,D) */+#define PXIPAL_INTPIN_MASK	(0xff << PXIPAL_INTPIN_OFFS)+++/* PCI Express Power Management Capability Header Register*/+/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/++#define PXPMC_CAP_ID_OFFS		0 /* Capability ID */+#define PXPMC_CAP_ID_MASK		(0xff << PXPMC_CAP_ID_OFFS)++#define PXPMC_NEXT_PTR_OFFS		8 /* Next Item Pointer */+#define PXPMC_NEXT_PTR_MASK		(0xff << PXPMC_NEXT_PTR_OFFS)++#define PXPMC_PMC_VER_OFFS		16 /* PCI Power Management Capability Version*/+#define PXPMC_PMC_VER_MASK		(0x7 << PXPMC_PMC_VER_OFFS)++#define PXPMC_DSI 				BIT21/* Device Specific Initialization */++#define PXPMC_AUX_CUR_OFFS		22 /* Auxiliary Current Requirements */+#define PXPMC_AUX_CUR_MASK		(0x7 << PXPMC_AUX_CUR_OFFS)++#define PXPMC_D1_SUP 			BIT25 /* D1 Power Management support*/++#define PXPMC_D2_SUP 			BIT26 /* D2 Power Management support*/++#define PXPMC_PME_SUP_OFFS		27 /* PM Event generation support*/+#define PXPMC_PME_SUP_MASK		(0x1f << PXPMC_PME_SUP_OFFS)++/* PCI Express Power Management Control and Status Register*/+/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/++#define PXPMSC_PM_STATE_OFFS	0	/* Power State */+#define PXPMSC_PM_STATE_MASK	(0x3 << PXPMSC_PM_STATE_OFFS)+#define PXPMSC_PM_STATE_D0		(0x0 << PXPMSC_PM_STATE_OFFS)+#define PXPMSC_PM_STATE_D1		(0x1 << PXPMSC_PM_STATE_OFFS)+#define PXPMSC_PM_STATE_D2		(0x2 << PXPMSC_PM_STATE_OFFS)+#define PXPMSC_PM_STATE_D3		(0x3 << PXPMSC_PM_STATE_OFFS)++#define PXPMSC_PME_EN			BIT8/* PM_PME Message Generation Enable */++#define PXPMSC_PM_DATA_SEL_OFFS	9	/* Data Select*/+#define PXPMSC_PM_DATA_SEL_MASK	(0xf << PXPMSC_PM_DATA_SEL_OFFS)++#define PXPMSC_PM_DATA_SCALE_OFFS	13	/* Data Scale */+#define PXPMSC_PM_DATA_SCALE_MASK	(0x3 << PXPMSC_PM_DATA_SCALE_OFFS)++#define PXPMSC_PME_STAT				BIT15/* PME Status */++#define PXPMSC_PM_DATA_OFFS			24		/* State Data */+#define PXPMSC_PM_DATA_MASK			(0xff << PXPMSC_PM_DATA_OFFS)+++/* PCI Express MSI Message Control Register*/								 +/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/++#define PXMMC_CAP_ID_OFFS			0 /* Capability ID */+#define PXMMC_CAP_ID_MASK			(0xff << PXMMC_CAP_ID_OFFS)++#define PXMMC_NEXT_PTR_OFFS			8 /* Next Item Pointer */+#define PXMMC_NEXT_PTR_MASK			(0xff << PXMMC_NEXT_PTR_OFFS)++#define PXMMC_MSI_EN				BIT18 /* MSI Enable */++#define PXMMC_MULTI_CAP_OFFS		17 /* Multiple Message Capable */+#define PXMMC_MULTI_CAP_MASK		(0x7 << PXMMC_MULTI_CAP_OFFS)++#define PXMMC_MULTI_EN_OFFS			20  /* Multiple Messages Enable */+#define PXMMC_MULTI_EN_MASK			(0x7 << PXMMC_MULTI_EN_OFFS)++#define PXMMC_ADDR64				BIT23	/* 64-bit Addressing Capable */+++/* PCI Express MSI Message Address Register*/+/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/++#define PXMMA_MSI_ADDR_OFFS			2 /* Message Address  corresponds to +										Address[31:2] of the MSI MWr TLP*/+#define PXMMA_MSI_ADDR_MASK			(0x3fffffff << PXMMA_MSI_ADDR_OFFS)+++/* PCI Express MSI Message Address (High) Register */+/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/++#define PXMMA_MSI_ADDR_H_OFFS		0 /* Message Upper Address corresponds to +											Address[63:32] of the MSI MWr TLP*/+#define PXMMA_MSI_ADDR_H_MASK		(0xffffffff << PXMMA_MSI_ADDR_H_OFFS )+++/* PCI Express MSI Message Data Register*/+/*PEX_MSI_MESSAGE_DATA (PXMMD)*/++#define PXMMD_MSI_DATA_OFFS 		0 /* Message Data */+#define PXMMD_MSI_DATA_MASK 		(0xffff << PXMMD_MSI_DATA_OFFS )+++/* PCI Express Capability Register*/								 +/*PEX_CAPABILITY_REG (PXCR)*/++#define PXCR_CAP_ID_OFFS			0	/* Capability ID*/+#define PXCR_CAP_ID_MASK			(0xff << PXCR_CAP_ID_OFFS)++#define PXCR_NEXT_PTR_OFFS			8 /* Next Item Pointer*/+#define PXCR_NEXT_PTR_MASK			(0xff << PXCR_NEXT_PTR_OFFS)++#define PXCR_CAP_VER_OFFS			16 /* Capability Version*/+#define PXCR_CAP_VER_MASK			(0xf << PXCR_CAP_VER_OFFS)++#define PXCR_DEV_TYPE_OFFS			20 /*  Device/Port Type*/+#define PXCR_DEV_TYPE_MASK			(0xf << PXCR_DEV_TYPE_OFFS)++#define PXCR_SLOT_IMP 				BIT24 /* Slot Implemented*/++#define PXCR_INT_MSG_NUM_OFFS		25 /* Interrupt Message Number*/+#define PXCR_INT_MSG_NUM_MASK		(0x1f << PXCR_INT_MSG_NUM_OFFS)+++/* PCI Express Device Capabilities Register */+/*PEX_DEV_CAPABILITY_REG (PXDCR)*/++#define PXDCR_MAX_PLD_SIZE_SUP_OFFS			0 /* Maximum Payload Size Supported*/+#define PXDCR_MAX_PLD_SIZE_SUP_MASK			(0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)++#define PXDCR_EP_L0S_ACC_LAT_OFFS			6/* Endpoint L0s Acceptable Latency*/+#define PXDCR_EP_L0S_ACC_LAT_MASK			(0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS		(0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS		(0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS	(0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS	(0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_512NS_1US		(0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_1US_2US		(0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_2US_4US		(0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)+#define PXDCR_EP_L0S_ACC_LAT_4US_MORE		(0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)++#define PXDCR_EP_L1_ACC_LAT_OFFS 			9 /* Endpoint L1 Acceptable Latency*/+#define PXDCR_EP_L1_ACC_LAT_MASK			(0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)+#define PXDCR_EP_L1_ACC_LAT_64NS_LESS       (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_64NS_128NS      (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_128NS_256NS     (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_256NS_512NS     (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_512NS_1US       (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_1US_2US         (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_2US_4US         (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS) +#define PXDCR_EP_L1_ACC_LAT_4US_MORE        (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS) +++#define PXDCR_ATT_BUT_PRS_OFFS				12 /* Attention Button Present*/+#define PXDCR_ATT_BUT_PRS_MASK				BIT12+#define PXDCR_ATT_BUT_PRS_IMPLEMENTED		BIT12++#define PXDCR_ATT_IND_PRS_OFFS				13 /* Attention Indicator Present*/+#define PXDCR_ATT_IND_PRS_MASK				BIT13+#define PXDCR_ATT_IND_PRS_IMPLEMENTED		BIT13++#define PXDCR_PWR_IND_PRS_OFFS        		14/* Power Indicator Present*/+#define PXDCR_PWR_IND_PRS_MASK       		BIT14+#define PXDCR_PWR_IND_PRS_IMPLEMENTED		BIT14++#define PXDCR_CAP_SPL_VAL_OFFS				18 /*Captured Slot Power Limit +												 Value*/+#define PXDCR_CAP_SPL_VAL_MASK				(0xff << PXDCR_CAP_SPL_VAL_OFFS)++#define PXDCR_CAP_SP_LSCL_OFFS				26 /* Captured Slot Power Limit+												  Scale */+#define PXDCR_CAP_SP_LSCL_MASK				(0x3 << PXDCR_CAP_SP_LSCL_OFFS)++/* PCI Express Device Control Status Register */+/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/++#define PXDCSR_COR_ERR_REP_EN		BIT0 /* Correctable Error Reporting Enable*/+#define PXDCSR_NF_ERR_REP_EN		BIT1 /* Non-Fatal Error Reporting Enable*/+#define PXDCSR_F_ERR_REP_EN			BIT2 /* Fatal Error Reporting Enable*/+#define PXDCSR_UR_REP_EN			BIT3 /* Unsupported Request (UR) +													Reporting Enable*/+#define PXDCSR_EN_RO 				BIT4 /* Enable Relaxed Ordering*/++#define PXDCSR_MAX_PLD_SZ_OFFS		5	 /* Maximum Payload Size*/+#define PXDCSR_MAX_PLD_SZ_MASK		(0x7 << PXDCSR_MAX_PLD_SZ_OFFS)+#define PXDCSR_MAX_PLD_SZ_128B		(0x0 << PXDCSR_MAX_PLD_SZ_OFFS)+#define PXDCSR_EN_NS				BIT11  /* Enable No Snoop*/++#define PXDCSR_MAX_RD_RQ_SZ_OFFS	12 /* Maximum Read Request Size*/+#define PXDCSR_MAX_RD_RQ_SZ_MASK	(0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)+#define PXDCSR_MAX_RD_RQ_SZ_128B	(0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)+#define PXDCSR_MAX_RD_RQ_SZ_256B	(0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)+#define PXDCSR_MAX_RD_RQ_SZ_512B	(0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)+#define PXDCSR_MAX_RD_RQ_SZ_1KB		(0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)+#define PXDCSR_MAX_RD_RQ_SZ_2KB		(0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)+#define PXDCSR_MAX_RD_RQ_SZ_4KB		(0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)++#define PXDCSR_COR_ERR_DET 			BIT16 /* Correctable Error Detected*/+#define PXDCSR_NF_ERR_DET 			BIT17 /* Non-Fatal Error Detected.*/+#define PXDCSR_F_ERR_DET 			BIT18 /* Fatal Error Detected.*/+#define PXDCSR_UR_DET				BIT19 /* Unsupported Request Detected */+#define PXDCSR_AUX_PWR_DET 			BIT20 /* Reserved*/++#define PXDCSR_TRANS_PEND_OFFS 			21 /* Transactions Pending*/+#define PXDCSR_TRANS_PEND_MASK 			BIT21+#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)+++/* PCI Express Link Capabilities Register*/+/*PEX_LINK_CAPABILITY_REG (PXLCR)*/++#define PXLCR_MAX_LINK_SPD_OFFS		0 /* Maximum Link Speed*/+#define PXLCR_MAX_LINK_SPD_MASK		(0xf << PXLCR_MAX_LINK_SPD_OFFS)++#define PXLCR_MAX_LNK_WDTH_OFFS 	3 /* Maximum Link Width*/+#define PXLCR_MAX_LNK_WDTH_MASK		(0x3f << PXLCR_MAX_LNK_WDTH_OFFS)++#define PXLCR_ASPM_SUP_OFFS 		10 /* Active State Link PM Support*/+#define PXLCR_ASPM_SUP_MASK			(0x3 << PXLCR_ASPM_SUP_OFFS)++#define PXLCR_L0S_EXT_LAT_OFFS 			12 /* L0s Exit Latency*/+#define PXLCR_L0S_EXT_LAT_MASK			(0x7 << PXLCR_L0S_EXT_LAT_OFFS)+#define PXLCR_L0S_EXT_LAT_64NS_LESS     (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)  +#define PXLCR_L0S_EXT_LAT_64NS_128NS   	(0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)  +#define PXLCR_L0S_EXT_LAT_128NS_256NS   (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)  +#define PXLCR_L0S_EXT_LAT_256NS_512NS   (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)  +#define PXLCR_L0S_EXT_LAT_512NS_1US     (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)  +#define PXLCR_L0S_EXT_LAT_1US_2US       (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)  +#define PXLCR_L0S_EXT_LAT_2US_4US       (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)  ++#define PXLCR_POR_TNUM_OFFS 			24 /* Port Number */+#define PXLCR_POR_TNUM_MASK				(0xff << PXLCR_POR_TNUM_OFFS)++/* PCI Express Link Control Status Register */+/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/++#define PXLCSR_ASPM_CNT_OFFS			0 /* Active State Link PM Control */+#define PXLCSR_ASPM_CNT_MASK			(0x3 << PXLCSR_ASPM_CNT_OFFS)+#define PXLCSR_ASPM_CNT_DISABLED		(0x0 << PXLCSR_ASPM_CNT_OFFS)+#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP		(0x1 << PXLCSR_ASPM_CNT_OFFS)+#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP		(0x2 << PXLCSR_ASPM_CNT_OFFS)+#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP	(0x3 << PXLCSR_ASPM_CNT_OFFS)++#define PXLCSR_RCB_OFFS				3 /* Read Completion Boundary */+#define PXLCSR_RCB_MASK				BIT3+#define PXLCSR_RCB_64B				(0 << PXLCSR_RCB_OFFS)+#define PXLCSR_RCB_128B				(1 << PXLCSR_RCB_OFFS)++#define PXLCSR_LNK_DIS 				BIT4 /* Link Disable */+#define PXLCSR_RETRN_LNK 			BIT5 /* Retrain Link */+#define PXLCSR_CMN_CLK_CFG			BIT6 /* Common Clock Configuration */+#define PXLCSR_EXTD_SNC 			BIT7 /* Extended Sync */++#define PXLCSR_LNK_SPD_OFFS 		16 /* Link Speed */+#define PXLCSR_LNK_SPD_MASK			(0xf << PXLCSR_LNK_SPD_OFFS)++#define PXLCSR_NEG_LNK_WDTH_OFFS	20  /* Negotiated Link Width */+#define PXLCSR_NEG_LNK_WDTH_MASK 	(0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)+#define PXLCSR_NEG_LNK_WDTH_X1		(0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)++#define PXLCSR_LNK_TRN 				BIT27 /* Link Training */++#define PXLCSR_SLT_CLK_CFG_OFFS		28 /* Slot Clock Configuration */+#define PXLCSR_SLT_CLK_CFG_MASK		BIT28+#define PXLCSR_SLT_CLK_CFG_INDPNT	(0x0 << PXLCSR_SLT_CLK_CFG_OFFS)+#define PXLCSR_SLT_CLK_CFG_REF		(0x1 << PXLCSR_SLT_CLK_CFG_OFFS)+								+/* PCI Express Advanced Error Report Header Register */								 +/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/++/* PCI Express Uncorrectable Error Status Register*/+/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/++/* PCI Express Uncorrectable Error Mask Register */+/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/++/* PCI Express Uncorrectable Error Severity Register */+/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/++/* PCI Express Correctable Error Status Register */+/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/++/* PCI Express Correctable Error Mask Register */+/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/++/* PCI Express Advanced Error Capability and Control Register*/+/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/++/* PCI Express Header Log First DWORD Register*/+/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/++/* PCI Express Header Log Second DWORD Register*/+/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/++/* PCI Express Header Log Third DWORD Register*/+/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/++/* PCI Express Header Log Fourth DWORD Register*/+/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* #ifndef __INCPEXREGSH */++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c	2010-11-09 20:28:11.822495468 +0100@@ -0,0 +1,313 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "mvPex.h"++//#define MV_DEBUG+/* defines  */       +#ifdef MV_DEBUG         +	#define DB(x)	x+#else                +	#define DB(x)    +#endif	             ++/* locals */         +typedef struct+{+	MV_U32 data;+	MV_U32 mask;+}PEX_HEADER_DATA;++/* local function forwad decleration */+MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func, +                        MV_U32 regOff);+MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev, +                           MV_U32 func, MV_U32 regOff, MV_U32 data);+void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);+++PEX_HEADER_DATA configHdr[16] = +{+{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */+{0x00100007, 0x0000ffff}, /*[status register, command register] */  +{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */+{0x00010008, 0x00000000},  /*[BIST, header type, latency time, cache line] */+{0x00000000, 0x00000000},  /*[base address 0] */             +{0x00000000, 0x00000000},  /*[base address 1] */             +{0x00000000, 0x00ffffff},  /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */         +{0x0000f101, 0x00000000},  /*[secondary status ,IO limit, IO base] */+{0x9ff0a000, 0x00000000},  /*[memory limit, memory base] */                +{0x0001fff1, 0x00000000},  /*[prefetch memory limit, prefetch memory base] */       +{0xffffffff, 0x00000000},  /*[prefetch memory base upper] */ +{0x00000000, 0x00000000},  /*[prefetch memory limit upper] */+{0xeffff000, 0x00000000},  /*[IO limit upper 16 bits, IO base upper 16 bits] */      +{0x00000000, 0x00000000},  /*[reserved, capability pointer] */ +{0x00000000, 0x00000000},  /*[expansion ROM base address] */ +{0x00000000, 0x000000FF},  /*[bridge control, interrupt pin, interrupt line] */             +};+++#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \+																(data & configHdr[offset/4].mask))+#define HEADER_READ(offset) configHdr[offset/4].data++/*******************************************************************************+* mvVrtBrgPexInit - Initialize PEX interfaces+*+* DESCRIPTION:+*+* This function is responsible of intialization of the Pex Interface , It +* configure the Pex Bars and Windows in the following manner:+*+*  Assumptions : +*				Bar0 is always internal registers bar+*			    Bar1 is always the DRAM bar+*				Bar2 is always the Device bar+*+*  1) Sets the Internal registers bar base by obtaining the base from+*	  the CPU Interface+*  2) Sets the DRAM bar base and size by getting the base and size from+*     the CPU Interface when the size is the sum of all enabled DRAM +*	  chip selects and the base is the base of CS0 .+*  3) Sets the Device bar base and size by getting these values from the +*     CPU Interface when the base is the base of the lowest base of the+*     Device chip selects, and the +*+*+* INPUT:+*+*       pexIf   -  PEX interface number.+*+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM+*+*******************************************************************************/+MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)+{+	/* reset PEX tree to recover previous U-boot/Boot configurations */+	MV_U32 localBus = mvPexLocalBusNumGet(pexIf);+++	resetPexConfig(pexIf, localBus, 1);+	return MV_OK;+}+++MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func, +                        MV_U32 regOff)+{+	+	MV_U32 localBus = mvPexLocalBusNumGet(pexIf);+	MV_U32 localDev = mvPexLocalDevNumGet(pexIf);+	MV_U32 val;  +	if(bus == localBus)+	{+		if(dev > 1)+		{+/* on the local device allow only device #0 & #1 */+			return 0xffffffff;+		}+		else+		if (dev == localDev)+		{+			/* read the memory controller registers */+			return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);+		}+		else+		{+			/* access the virtual brg header */+			return HEADER_READ(regOff);+		}+	}+	else+	if(bus == (localBus + 1))+	{+		/* access the device behind the virtual bridge */+		if((dev == localDev) || (dev > 1))+		{+			return 0xffffffff;+		}+		else+		{+			/* access the device behind the virtual bridge, in this case +			*  change the bus number to the local bus number in order to +			*  generate type 0 config cycle+			*/			+			mvPexLocalBusNumSet(pexIf, bus);+			mvPexLocalDevNumSet(pexIf, 1);+			val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);+			mvPexLocalBusNumSet(pexIf, localBus);+			mvPexLocalDevNumSet(pexIf, localDev);+			return val;+		}+	}+	/* for all other devices use the HW function to get the +	*  requested registers+	*/+	mvPexLocalDevNumSet(pexIf, 1);+	val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);+	mvPexLocalDevNumSet(pexIf, localDev);	+	return val;+}+++MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev, +                           MV_U32 func, MV_U32 regOff, MV_U32 data)+{+	MV_U32 localBus = mvPexLocalBusNumGet(pexIf);+	MV_U32 localDev = mvPexLocalDevNumGet(pexIf);+	MV_STATUS	status;++	if(bus == localBus)+	{+		if(dev > 1)+		{+			/* on the local device allow only device #0 & #1 */+			return MV_ERROR;+		}+		else+		if (dev == localDev)+		{+			/* read the memory controller registers */+			return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);			+		}+		else+		{+			/* access the virtual brg header */+			HEADER_WRITE(data, regOff);+			return MV_OK;+		}+	}+	else+	if(bus == (localBus + 1))+	{+		/* access the device behind the virtual bridge */+		if((dev == localDev) || (dev > 1))+		{+			return MV_ERROR;+		}+		else+		{+			/* access the device behind the virtual bridge, in this case +			*  change the bus number to the local bus number in order to +			*  generate type 0 config cycle+			*/+			//return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);+			mvPexLocalBusNumSet(pexIf, bus);+			mvPexLocalDevNumSet(pexIf, 1);+			status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);+			mvPexLocalBusNumSet(pexIf, localBus);+			mvPexLocalDevNumSet(pexIf, localDev);+			return status;++		}+	}+	/* for all other devices use the HW function to get the +	*  requested registers+	*/+	mvPexLocalDevNumSet(pexIf, 1);+	status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);+	mvPexLocalDevNumSet(pexIf, localDev);+	return status;+}+++++void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)+{+	MV_U32 tData;+	MV_U32 i;++	/* restore the PEX configuration to initialization state */+	/* in case PEX P2P call recursive and reset config */+	tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);+	if(tData != 0xffffffff)+	{+		/* agent had been found - check whether P2P */+		tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);+		if((tData & 0xffff0000) == 0x06040000)+		{/* P2P */+			/* get the sec bus and the subordinate */+			MV_U32 secBus;	+			tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);+			secBus = ((tData >> 8) & 0xff);+			/* now scan on sec bus */+			for(i = 0;i < 0xff;i++)+			{+				resetPexConfig(pexIf, secBus, i);+			}+			/* now reset this device */+			DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));+			mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0); +			DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));+		}+	}+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h	2010-11-09 20:28:11.861239834 +0100@@ -0,0 +1,82 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCVRTBRGPEXH+#define __INCVRTBRGPEXH+++/* Global Functions prototypes */+/* mvPexInit - Initialize PEX interfaces*/+MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);++/* mvPexConfigRead - Read from configuration space */+MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,+						MV_U32 func,MV_U32 regOff);++/* mvPexConfigWrite - Write to configuration space */+MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,+                           MV_U32 func, MV_U32 regOff, MV_U32 data);+++#endif /* #ifndef __INCPEXH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c	2010-11-09 20:28:11.901246212 +0100@@ -0,0 +1,1522 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#include "mvOs.h"+#include "sflash/mvSFlash.h"+#include "sflash/mvSFlashSpec.h"+#include "spi/mvSpi.h"+#include "spi/mvSpiCmnd.h"+#include "ctrlEnv/mvCtrlEnvLib.h"++/*#define MV_DEBUG*/+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++/* Globals */+static MV_SFLASH_DEVICE_PARAMS sflash[] = {+    /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */+    {+     MV_M25P_WREN_CMND_OPCD,+     MV_M25P_WRDI_CMND_OPCD,+     MV_M25P_RDID_CMND_OPCD,+     MV_M25P_RDSR_CMND_OPCD,+     MV_M25P_WRSR_CMND_OPCD,+     MV_M25P_READ_CMND_OPCD,+     MV_M25P_FAST_RD_CMND_OPCD,+     MV_M25P_PP_CMND_OPCD,+     MV_M25P_SE_CMND_OPCD,+     MV_M25P_BE_CMND_OPCD,+     MV_M25P_RES_CMND_OPCD,+     MV_SFLASH_NO_SPECIFIC_OPCD,    /* power save not supported */+     MV_M25P32_SECTOR_SIZE,+     MV_M25P32_SECTOR_NUMBER,+     MV_M25P_PAGE_SIZE,+     "ST M25P32",+     MV_M25PXXX_ST_MANF_ID,+     MV_M25P32_DEVICE_ID,+     MV_M25P32_MAX_SPI_FREQ,+     MV_M25P32_MAX_FAST_SPI_FREQ,+     MV_M25P32_FAST_READ_DUMMY_BYTES+    },+    /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */+    {+     MV_M25P_WREN_CMND_OPCD,+     MV_M25P_WRDI_CMND_OPCD,+     MV_M25P_RDID_CMND_OPCD,+     MV_M25P_RDSR_CMND_OPCD,+     MV_M25P_WRSR_CMND_OPCD,+     MV_M25P_READ_CMND_OPCD,+     MV_M25P_FAST_RD_CMND_OPCD,+     MV_M25P_PP_CMND_OPCD,+     MV_M25P_SE_CMND_OPCD,+     MV_M25P_BE_CMND_OPCD,+     MV_M25P_RES_CMND_OPCD,+     MV_SFLASH_NO_SPECIFIC_OPCD,    /* power save not supported */+     MV_M25P64_SECTOR_SIZE,+     MV_M25P64_SECTOR_NUMBER,+     MV_M25P_PAGE_SIZE,+     "ST M25P64",+     MV_M25PXXX_ST_MANF_ID,+     MV_M25P64_DEVICE_ID,+     MV_M25P64_MAX_SPI_FREQ,+     MV_M25P64_MAX_FAST_SPI_FREQ,+     MV_M25P64_FAST_READ_DUMMY_BYTES+    },+    /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */+    {+     MV_M25P_WREN_CMND_OPCD,+     MV_M25P_WRDI_CMND_OPCD,+     MV_M25P_RDID_CMND_OPCD,+     MV_M25P_RDSR_CMND_OPCD,+     MV_M25P_WRSR_CMND_OPCD,+     MV_M25P_READ_CMND_OPCD,+     MV_M25P_FAST_RD_CMND_OPCD,+     MV_M25P_PP_CMND_OPCD,+     MV_M25P_SE_CMND_OPCD,+     MV_M25P_BE_CMND_OPCD,+     MV_M25P_RES_CMND_OPCD,+     MV_SFLASH_NO_SPECIFIC_OPCD,    /* power save not supported */+     MV_M25P128_SECTOR_SIZE,+     MV_M25P128_SECTOR_NUMBER,+     MV_M25P_PAGE_SIZE,+     "ST M25P128",+     MV_M25PXXX_ST_MANF_ID,+     MV_M25P128_DEVICE_ID,+     MV_M25P128_MAX_SPI_FREQ,+     MV_M25P128_MAX_FAST_SPI_FREQ,+     MV_M25P128_FAST_READ_DUMMY_BYTES+    },+    /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */+    {+     MV_MX25L_WREN_CMND_OPCD,+     MV_MX25L_WRDI_CMND_OPCD,+     MV_MX25L_RDID_CMND_OPCD,+     MV_MX25L_RDSR_CMND_OPCD,+     MV_MX25L_WRSR_CMND_OPCD,+     MV_MX25L_READ_CMND_OPCD,+     MV_MX25L_FAST_RD_CMND_OPCD,+     MV_MX25L_PP_CMND_OPCD,+     MV_MX25L_SE_CMND_OPCD,+     MV_MX25L_BE_CMND_OPCD,+     MV_MX25L_RES_CMND_OPCD,+     MV_MX25L_DP_CMND_OPCD,+     MV_MX25L6405_SECTOR_SIZE,+     MV_MX25L6405_SECTOR_NUMBER,+     MV_MXIC_PAGE_SIZE,+     "MXIC MX25L6405",+     MV_MXIC_MANF_ID,+     MV_MX25L6405_DEVICE_ID,+     MV_MX25L6405_MAX_SPI_FREQ,+     MV_MX25L6405_MAX_FAST_SPI_FREQ,+     MV_MX25L6405_FAST_READ_DUMMY_BYTES+    },+    /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */+    {+     MV_S25FL_WREN_CMND_OPCD,+     MV_S25FL_WRDI_CMND_OPCD,+     MV_S25FL_RDID_CMND_OPCD,+     MV_S25FL_RDSR_CMND_OPCD,+     MV_S25FL_WRSR_CMND_OPCD,+     MV_S25FL_READ_CMND_OPCD,+     MV_S25FL_FAST_RD_CMND_OPCD,+     MV_S25FL_PP_CMND_OPCD,+     MV_S25FL_SE_CMND_OPCD,+     MV_S25FL_BE_CMND_OPCD,+     MV_S25FL_RES_CMND_OPCD,+     MV_S25FL_DP_CMND_OPCD,+     MV_S25FL128_SECTOR_SIZE,+     MV_S25FL128_SECTOR_NUMBER,+     MV_S25FL_PAGE_SIZE,+     "SPANSION S25FL128",+     MV_SPANSION_MANF_ID,+     MV_S25FL128_DEVICE_ID,+     MV_S25FL128_MAX_SPI_FREQ,+     MV_M25P128_MAX_FAST_SPI_FREQ,+     MV_M25P128_FAST_READ_DUMMY_BYTES+    }+};++/* Static Functions */+static MV_STATUS    mvWriteEnable   (MV_SFLASH_INFO * pFlinfo);+static MV_STATUS    mvStatusRegGet  (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);+static MV_STATUS    mvStatusRegSet  (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);+static MV_STATUS    mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);+static MV_STATUS    mvSFlashPageWr  (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \+							         MV_U8* pPageBuff, MV_U32 buffSize);+static MV_STATUS    mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \+                                            MV_U8* manId, MV_U16* devId);++/*******************************************************************************+* mvWriteEnable - serialize the write enable sequence+*+* DESCRIPTION:+*       transmit the sequence for write enable+*+********************************************************************************/+static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)+{+	MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];+++    cmd[0] = sflash[pFlinfo->index].opcdWREN;++	return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);+}++/*******************************************************************************+* mvStatusRegGet - Retrieve the value of the status register+*+* DESCRIPTION:+*       perform the RDSR sequence to get the 8bit status register+*+********************************************************************************/+static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];+	MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];+++++	cmd[0] = sflash[pFlinfo->index].opcdRDSR;++	if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,+                                         MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)+        return ret;++    *pStatReg = sr[0];++    return MV_OK;+}++/*******************************************************************************+* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared+*+* DESCRIPTION:+*       Block waiting for the WIP (write in progress) to be cleared+*+********************************************************************************/+static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)+{+    MV_STATUS ret;+	MV_U32 i;+    MV_U8 stat;++	for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)+	{+        if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)+            return ret;++		if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)+			return MV_OK;+	}++    DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)+	return MV_TIMEOUT;+}++/*******************************************************************************+* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be+*                         cleared after a chip erase command which is supposed+*                         to take about 2:30 minutes+*+* DESCRIPTION:+*       Block waiting for the WIP (write in progress) to be cleared+*+********************************************************************************/+static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)+{+    MV_STATUS ret;+	MV_U32 i;+    MV_U8 stat;++	for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)+	{+        if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)+            return ret;++		if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)+			return MV_OK;+	}++    DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)+	return MV_TIMEOUT;+}++/*******************************************************************************+*  mvStatusRegSet - Set the value of the 8bit status register+*+* DESCRIPTION:+*       Set the value of the 8bit status register+*+********************************************************************************/+static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];+++    /* Issue the Write enable command prior the WRSR command */+	if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)+		return ret;++    /* Write the SR with the new values */+    cmd[0] = sflash[pFlinfo->index].opcdWRSR;+	cmd[1] = sr;++	if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)+		return ret;++    if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)+		return ret;++    mvOsDelay(1);++    return MV_OK;+}++/*******************************************************************************+* mvSFlashPageWr - Write up to 256 Bytes in the same page+*+* DESCRIPTION:+*       Write a buffer up to the page size in length provided that the whole address+*		range is within the same page (alligned to page bounderies)+*+*******************************************************************************/+static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+							     MV_U8* pPageBuff, MV_U32 buffSize)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];+++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++	/* check that we do not cross the page bounderies */+    if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >+        sflash[pFlinfo->index].pageSize)+    {+        DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)+		return MV_OUT_OF_RANGE;+    }++	/* Issue the Write enable command prior the page program command */+	if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)+		return ret;++    cmd[0] = sflash[pFlinfo->index].opcdPP;+	cmd[1] = ((offset >> 16) & 0xFF);+	cmd[2] = ((offset >> 8) & 0xFF);+	cmd[3] = (offset & 0xFF);++	if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)+		return ret;++	if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)+		return ret;++	return MV_OK;+}++/*******************************************************************************+* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from+*       the device using the default RDID opcode and the default WREN opcode.+*+* DESCRIPTION:+*       This is used to detect a generic device that uses the default opcodes+*       for the WREN and RDID.+*+********************************************************************************/+static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)+{+    MV_STATUS ret;+    MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];+	MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];++++    /* Use the default RDID opcode to read the IDs */+    cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD;   /* unknown model try default */+	if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)+		return ret;++	*manId = id[0];+	*devId = 0;+	*devId |= (id[1] << 8);+	*devId |= id[2];++	return MV_OK;+}++/*+#####################################################################################+#####################################################################################+*/++/*******************************************************************************+* mvSFlashInit - Initialize the serial flash device+*+* DESCRIPTION:+*       Perform the neccessary initialization and configuration+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*           pFlinfo->baseAddr: base address in fast mode.+*           pFlinfo->index: Index of the flash in the sflash tabel. If the SPI+*                           flash device does not support read Id command with+*                           the standard opcode, then the user should supply this+*                           as an input to skip the autodetection process!!!!+*+* OUTPUT:+*       pFlinfo: pointer to the Flash information structure after detection+*           pFlinfo->manufacturerId: Manufacturer ID+*           pFlinfo->deviceId: Device ID+*           pFlinfo->sectorSize: size of the sector (all sectors are the same).+*           pFlinfo->sectorNumber: number of sectors.+*           pFlinfo->pageSize: size of the page.+*           pFlinfo->index: Index of the detected flash in the sflash tabel+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)+{+    MV_STATUS ret;+    MV_U8 manf;+    MV_U16 dev;+    MV_U32 indx;+    MV_BOOL detectFlag = MV_FALSE;++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */+    if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)+    {+        mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);+        return ret;+    }++    /* First try to read the Manufacturer and Device IDs */+    if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)+    {+        mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);+        return ret;+    }++    /* loop over the whole table and look for the appropriate SFLASH */+    for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)+    {+        if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))+        {+            pFlinfo->manufacturerId = manf;+            pFlinfo->deviceId = dev;+            pFlinfo->index = indx;+            detectFlag = MV_TRUE;+        }+    }++    if(!detectFlag)+    {+        mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);+        return MV_FAIL;+    }++    /* fill the info based on the model detected */+    pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;+    pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;+    pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;++    /* Set the SPI frequency to the MAX allowed for the device for best performance */+    if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)+    {+        mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);+        return ret;+    }++    /* As default lock the SR */+    if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)+        return ret;++	return MV_OK;+}++/*******************************************************************************+* mvSFlashSectorErase - Erasse a single sector of the serial flash+*+* DESCRIPTION:+*       Issue the erase sector command and address+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		secNumber: sector Number to erase (0 -> (sectorNumber-1))+*+* OUTPUT:+*       None+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];++    MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);+#if 0+    MV_U32 i;+    MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);+    MV_U32 erasedWord = 0xFFFFFFFF;+    MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));+    MV_BOOL eraseNeeded = MV_FALSE;+#endif+    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    /* check that the sector number is valid */+    if (secNumber >= pFlinfo->sectorNumber)+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }+    +    /* we don't want to access SPI in direct mode from in-direct API, +	becasue of timing issue between CS asserts. */+#if 0+    /* First compare to FF and check if erase is needed */+    for (i=0; i<wordsPerSector; i++)+    {+        if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)+        {+            eraseNeeded = MV_TRUE;+            break;+        }++        ++pW;+    }+    if (!eraseNeeded)+        return MV_OK;+#endif++    cmd[0] = sflash[pFlinfo->index].opcdSE;+	cmd[1] = ((secAddr >> 16) & 0xFF);+	cmd[2] = ((secAddr >> 8) & 0xFF);+	cmd[3] = (secAddr & 0xFF);++	/* Issue the Write enable command prior the sector erase command */+	if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)+		return ret;++	if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)+		return ret;++	if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)+		return ret;++	return MV_OK;+}++/*******************************************************************************+* mvSFlashChipErase - Erasse the whole serial flash+*+* DESCRIPTION:+*       Issue the bulk (chip) erase command+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*+* OUTPUT:+*       None+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];+++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    cmd[0] = sflash[pFlinfo->index].opcdBE;++	/* Issue the Write enable command prior the Bulk erase command */+	if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)+		return ret;++    if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)+		return ret;++	if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)+		return ret;++	return MV_OK;+}++/*******************************************************************************+* mvSFlashBlockRd - Read from the serial flash+*+* DESCRIPTION:+*       Issue the read command and address then perfom the needed read+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		offset: byte offset with the flash to start reading from+*		pReadBuff: pointer to the buffer to read the data in+*		buffSize: size of the buffer to read.+*+* OUTPUT:+*       pReadBuff: pointer to the buffer containing the read data+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+						   MV_U8* pReadBuff, MV_U32 buffSize)+{+	MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];+++    /* check for NULL pointer */+    if ((pFlinfo == NULL) || (pReadBuff == NULL))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    cmd[0] = sflash[pFlinfo->index].opcdREAD;+	cmd[1] = ((offset >> 16) & 0xFF);+	cmd[2] = ((offset >> 8) & 0xFF);+	cmd[3] = (offset & 0xFF);++	return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);+}++/*******************************************************************************+* mvSFlashFastBlockRd - Fast read from the serial flash+*+* DESCRIPTION:+*       Issue the fast read command and address then perfom the needed read+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		offset: byte offset with the flash to start reading from+*		pReadBuff: pointer to the buffer to read the data in+*		buffSize: size of the buffer to read.+*+* OUTPUT:+*       pReadBuff: pointer to the buffer containing the read data+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+						       MV_U8* pReadBuff, MV_U32 buffSize)+{+    MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];+    MV_STATUS ret;++    /* check for NULL pointer */+    if ((pFlinfo == NULL) || (pReadBuff == NULL))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    /* Set the SPI frequency to the MAX allowed for fast-read operations */+    mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);+    if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)+    {+        mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);+        return ret;+    }++    cmd[0] = sflash[pFlinfo->index].opcdFSTRD;+    cmd[1] = ((offset >> 16) & 0xFF);+    cmd[2] = ((offset >> 8) & 0xFF);+    cmd[3] = (offset & 0xFF);+++    ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,+                             sflash[pFlinfo->index].spiFastRdDummyBytes);++    /* Reset the SPI frequency to the MAX allowed for the device for best performance */+    if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)+    {+        mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);+        return ret;+    }++    return ret;+}+++/*******************************************************************************+* mvSFlashBlockWr - Write a buffer with any size+*+* DESCRIPTION:+*       write regardless of the page boundaries and size limit per Page+*		program command+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		offset: byte offset within the flash region+*		pWriteBuff: pointer to the buffer holding the data to program+*		buffSize: size of the buffer to write+*+* OUTPUT:+*       None+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+						   MV_U8* pWriteBuff, MV_U32 buffSize)+{+    MV_STATUS ret;+	MV_U32 data2write	= buffSize;+    MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));+    MV_U32 preAllSz		= (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);+	MV_U32 writeOffset	= offset;++    /* check for NULL pointer */+#ifndef CONFIG_MARVELL+    if(NULL == pWriteBuff)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }+#endif++    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++	/* check that the buffer size does not exceed the flash size */+    if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))+    {+        DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)+	    return MV_OUT_OF_RANGE;+    }++	/* check if the total block size is less than the first chunk remainder */+	if (data2write < preAllSz)+		preAllSz = data2write;++	/* check if programing does not start at a 64byte alligned offset */+	if (preAllSz)+	{+		if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)+			return ret;++		/* increment pointers and counters */+		writeOffset += preAllSz;+		data2write -= preAllSz;+		pWriteBuff += preAllSz;+	}++	/* program the data that fits in complete page chunks */+	while (data2write >= sflash[pFlinfo->index].pageSize)+	{+		if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)+			return ret;++		/* increment pointers and counters */+		writeOffset += sflash[pFlinfo->index].pageSize;+		data2write -= sflash[pFlinfo->index].pageSize;+		pWriteBuff += sflash[pFlinfo->index].pageSize;+	}++	/* program the last partial chunk */+	if (data2write)+	{+		if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)+			return ret;+	}++	return MV_OK;+}++/*******************************************************************************+* mvSFlashIdGet - Get the manufacturer and device IDs.+*+* DESCRIPTION:+*       Get the Manufacturer and device IDs from the serial flash through+*		writing the RDID command then reading 3 bytes of data. In case that+*       this command was called for the first time in order to detect the+*       manufacturer and device IDs, then the default RDID opcode will be used+*       unless the device index is indicated by the user (in case the SPI flash+*       does not use the default RDID opcode).+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		pManId: pointer to the 8bit variable to hold the manufacturing ID+*		pDevId: pointer to the 16bit variable to hold the device ID+*+* OUTPUT:+*		pManId: pointer to the 8bit variable holding the manufacturing ID+*		pDevId: pointer to the 16bit variable holding the device ID+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];+	MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];++++    /* check for NULL pointer */+    if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+        return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);+    else+        cmd[0] = sflash[pFlinfo->index].opcdRDID;++	if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)+		return ret;++	*pManId = id[0];+	*pDevId = 0;+	*pDevId |= (id[1] << 8);+	*pDevId |= id[2];++	return MV_OK;+}++/*******************************************************************************+* mvSFlashWpRegionSet - Set the Write-Protected region+*+* DESCRIPTION:+*       Set the Write-Protected region+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		wpRegion: which region will be protected+*+* OUTPUT:+*       None+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)+{+    MV_U8 wpMask;++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    /* Check if the chip is an ST flash; then WP supports only 3 bits */+    if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)+    {+        switch (wpRegion)+        {+            case MV_WP_NONE:+                wpMask = MV_M25P_STATUS_BP_NONE;+                break;++            case MV_WP_UPR_1OF128:+                DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)+                return MV_NOT_SUPPORTED;++            case MV_WP_UPR_1OF64:+                wpMask = MV_M25P_STATUS_BP_1_OF_64;+                break;++            case MV_WP_UPR_1OF32:+                wpMask = MV_M25P_STATUS_BP_1_OF_32;+                break;++            case MV_WP_UPR_1OF16:+                wpMask = MV_M25P_STATUS_BP_1_OF_16;+                break;++            case MV_WP_UPR_1OF8:+                wpMask = MV_M25P_STATUS_BP_1_OF_8;+                break;++            case MV_WP_UPR_1OF4:+                wpMask = MV_M25P_STATUS_BP_1_OF_4;+                break;++            case MV_WP_UPR_1OF2:+                wpMask = MV_M25P_STATUS_BP_1_OF_2;+                break;++            case MV_WP_ALL:+                wpMask = MV_M25P_STATUS_BP_ALL;+                break;++            default:+                DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)+                return MV_BAD_PARAM;+        }+    }+    /* check if the manufacturer is MXIC then the WP is 4bits */+    else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)+    {+        switch (wpRegion)+        {+            case MV_WP_NONE:+                wpMask = MV_MX25L_STATUS_BP_NONE;+                break;++            case MV_WP_UPR_1OF128:+                wpMask = MV_MX25L_STATUS_BP_1_OF_128;+                break;++            case MV_WP_UPR_1OF64:+                wpMask = MV_MX25L_STATUS_BP_1_OF_64;+                break;++            case MV_WP_UPR_1OF32:+                wpMask = MV_MX25L_STATUS_BP_1_OF_32;+                break;++            case MV_WP_UPR_1OF16:+                wpMask = MV_MX25L_STATUS_BP_1_OF_16;+                break;++            case MV_WP_UPR_1OF8:+                wpMask = MV_MX25L_STATUS_BP_1_OF_8;+                break;++            case MV_WP_UPR_1OF4:+                wpMask = MV_MX25L_STATUS_BP_1_OF_4;+                break;++            case MV_WP_UPR_1OF2:+                wpMask = MV_MX25L_STATUS_BP_1_OF_2;+                break;++            case MV_WP_ALL:+                wpMask = MV_MX25L_STATUS_BP_ALL;+                break;++            default:+                DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)+                return MV_BAD_PARAM;+        }+    }+    /* check if the manufacturer is SPANSION then the WP is 4bits */+    else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)+    {+        switch (wpRegion)+        {+            case MV_WP_NONE:+                wpMask = MV_S25FL_STATUS_BP_NONE;+                break;++            case MV_WP_UPR_1OF128:+                DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)+                return MV_NOT_SUPPORTED;++            case MV_WP_UPR_1OF64:+                wpMask = MV_S25FL_STATUS_BP_1_OF_64;+                break;++            case MV_WP_UPR_1OF32:+                wpMask = MV_S25FL_STATUS_BP_1_OF_32;+                break;++            case MV_WP_UPR_1OF16:+                wpMask = MV_S25FL_STATUS_BP_1_OF_16;+                break;++            case MV_WP_UPR_1OF8:+                wpMask = MV_S25FL_STATUS_BP_1_OF_8;+                break;++            case MV_WP_UPR_1OF4:+                wpMask = MV_S25FL_STATUS_BP_1_OF_4;+                break;++            case MV_WP_UPR_1OF2:+                wpMask = MV_S25FL_STATUS_BP_1_OF_2;+                break;++            case MV_WP_ALL:+                wpMask = MV_S25FL_STATUS_BP_ALL;+                break;+++            default:+                DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)+                return MV_BAD_PARAM;+        }+    }+    else+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    /* Verify that the SRWD bit is always set - register is s/w locked */+    wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;++	return mvStatusRegSet(pFlinfo, wpMask);+}++/*******************************************************************************+* mvSFlashWpRegionGet - Get the Write-Protected region configured+*+* DESCRIPTION:+*       Get from the chip the Write-Protected region configured+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		pWpRegion: pointer to the variable to return the WP region in+*+* OUTPUT:+*		wpRegion: pointer to the variable holding the WP region configured+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)+{+    MV_STATUS ret;+	MV_U8 reg;++    /* check for NULL pointer */+    if ((pFlinfo == NULL) || (pWpRegion == NULL))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    if ((ret = mvStatusRegGet(pFlinfo, ®)) != MV_OK)+        return ret;++    /* Check if the chip is an ST flash; then WP supports only 3 bits */+    if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)+    {+        switch ((reg & MV_M25P_STATUS_REG_WP_MASK))+        {+            case MV_M25P_STATUS_BP_NONE:+                *pWpRegion = MV_WP_NONE;+                break;++            case MV_M25P_STATUS_BP_1_OF_64:+                *pWpRegion = MV_WP_UPR_1OF64;+                break;++            case MV_M25P_STATUS_BP_1_OF_32:+                *pWpRegion = MV_WP_UPR_1OF32;+                break;++            case MV_M25P_STATUS_BP_1_OF_16:+                *pWpRegion = MV_WP_UPR_1OF16;+                break;++            case MV_M25P_STATUS_BP_1_OF_8:+                *pWpRegion = MV_WP_UPR_1OF8;+                break;++            case MV_M25P_STATUS_BP_1_OF_4:+                *pWpRegion = MV_WP_UPR_1OF4;+                break;++            case MV_M25P_STATUS_BP_1_OF_2:+                *pWpRegion = MV_WP_UPR_1OF2;+                break;++            case MV_M25P_STATUS_BP_ALL:+                *pWpRegion = MV_WP_ALL;+                break;++            default:+                DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)+                return MV_BAD_VALUE;+        }+    }+    /* check if the manufacturer is MXIC then the WP is 4bits */+    else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)+    {+        switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))+        {+            case MV_MX25L_STATUS_BP_NONE:+                *pWpRegion = MV_WP_NONE;+                break;++            case MV_MX25L_STATUS_BP_1_OF_128:+                *pWpRegion = MV_WP_UPR_1OF128;+                break;++            case MV_MX25L_STATUS_BP_1_OF_64:+                *pWpRegion = MV_WP_UPR_1OF64;+                break;++            case MV_MX25L_STATUS_BP_1_OF_32:+                *pWpRegion = MV_WP_UPR_1OF32;+                break;++            case MV_MX25L_STATUS_BP_1_OF_16:+                *pWpRegion = MV_WP_UPR_1OF16;+                break;++            case MV_MX25L_STATUS_BP_1_OF_8:+                *pWpRegion = MV_WP_UPR_1OF8;+                break;++            case MV_MX25L_STATUS_BP_1_OF_4:+                *pWpRegion = MV_WP_UPR_1OF4;+                break;++            case MV_MX25L_STATUS_BP_1_OF_2:+                *pWpRegion = MV_WP_UPR_1OF2;+                break;++            case MV_MX25L_STATUS_BP_ALL:+                *pWpRegion = MV_WP_ALL;+                break;++            default:+                DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)+                return MV_BAD_VALUE;+        }+    }+    /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */+    else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)+    {+        switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))+        {+            case MV_S25FL_STATUS_BP_NONE:+                *pWpRegion = MV_WP_NONE;+                break;++            case MV_S25FL_STATUS_BP_1_OF_64:+                *pWpRegion = MV_WP_UPR_1OF64;+                break;++            case MV_S25FL_STATUS_BP_1_OF_32:+                *pWpRegion = MV_WP_UPR_1OF32;+                break;++            case MV_S25FL_STATUS_BP_1_OF_16:+                *pWpRegion = MV_WP_UPR_1OF16;+                break;++            case MV_S25FL_STATUS_BP_1_OF_8:+                *pWpRegion = MV_WP_UPR_1OF8;+                break;++            case MV_S25FL_STATUS_BP_1_OF_4:+                *pWpRegion = MV_WP_UPR_1OF4;+                break;++            case MV_S25FL_STATUS_BP_1_OF_2:+                *pWpRegion = MV_WP_UPR_1OF2;+                break;++            case MV_S25FL_STATUS_BP_ALL:+                *pWpRegion = MV_WP_ALL;+                break;++            default:+                DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)+                return MV_BAD_VALUE;+        }+    }+    else+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++	return MV_OK;+}++/*******************************************************************************+* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp+*		pin should be low to take effect+*+* DESCRIPTION:+*       Lock the access to the Status Register for writing. This will+*		cause the flash to enter the hardware protection mode if the W/Vpp+*		is low. If the W/Vpp is hi, the chip will be in soft protection mode, but+*		the register will continue to be writable if WREN sequence was used.+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*		srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism+*+* OUTPUT:+*       None+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)+{+    MV_STATUS ret;+	MV_U8 reg;++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    if ((ret = mvStatusRegGet(pFlinfo, ®)) != MV_OK)+        return ret;++	if (srLock)+		reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;+	else+		reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;++	return mvStatusRegSet(pFlinfo, reg);+}++/*******************************************************************************+* mvSFlashSizeGet - Get the size of the SPI flash+*+* DESCRIPTION:+*       based on the sector number and size of each sector calculate the total+*       size of the flash memory.+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*+* OUTPUT:+*       None.+*+* RETURN:+*       Size of the flash in bytes.+*+*+*******************************************************************************/+MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)+{+    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return 0;+    }++    return (pFlinfo->sectorSize * pFlinfo->sectorNumber);+}++/*******************************************************************************+* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode+*+* DESCRIPTION:+*       Enter a special power save mode.+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*+* OUTPUT:+*       None.+*+* RETURN:+*       Size of the flash in bytes.+*+*+*******************************************************************************/+MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];+++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return 0;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    /* check that power save mode is supported in the specific device */+    if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)+    {+        DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)+        return MV_NOT_SUPPORTED;+    }++    cmd[0] = sflash[pFlinfo->index].opcdPwrSave;++    if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)+		return ret;++	return MV_OK;++}++/*******************************************************************************+* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode+*+* DESCRIPTION:+*       Exit the deep power save mode.+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*+* OUTPUT:+*       None.+*+* RETURN:+*       Size of the flash in bytes.+*+*+*******************************************************************************/+MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)+{+    MV_STATUS ret;+	MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];+++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return 0;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return MV_BAD_PARAM;+    }++    /* check that power save mode is supported in the specific device */+    if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)+    {+        DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)+        return MV_NOT_SUPPORTED;+    }++    cmd[0] = sflash[pFlinfo->index].opcdRES;++    if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)+		return ret;++    /* add the delay needed for the device to wake up */+    mvOsDelay(MV_MXIC_DP_EXIT_DELAY);   /* 30 ms */++	return MV_OK;++}++/*******************************************************************************+* mvSFlashModelGet - Retreive the string with the device manufacturer and model+*+* DESCRIPTION:+*       Retreive the string with the device manufacturer and model+*+* INPUT:+*       pFlinfo: pointer to the Flash information structure+*+* OUTPUT:+*       None.+*+* RETURN:+*       pointer to the string indicating the device manufacturer and model+*+*+*******************************************************************************/+const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)+{+    static const MV_8 * unknModel = (const MV_8 *)"Unknown";++    /* check for NULL pointer */+    if (pFlinfo == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return 0;+    }++    /* Protection - check if the model was detected */+    if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))+    {+        DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)+        return unknModel;+    }++    return sflash[pFlinfo->index].deviceModel;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h	2010-11-09 20:28:11.941246441 +0100@@ -0,0 +1,166 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSFlashH+#define __INCmvSFlashH++#include "mvTypes.h"++/* MCAROS */+#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz)    (pgSz-1)+#define MV_ARRAY_SIZE(a)                    ((sizeof(a)) / (sizeof(a[0])))++/* Constants */+#define MV_INVALID_DEVICE_NUMBER            0xFFFFFFFF+/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/+#define MV_SFLASH_BASIC_SPI_FREQ            10000000+/* enumerations */+typedef enum+{+	MV_WP_NONE,             /* Unprotect the whole chip */+    MV_WP_UPR_1OF128,       /* Write protect the upper 1/128 part */+    MV_WP_UPR_1OF64,        /* Write protect the upper 1/64 part */+	MV_WP_UPR_1OF32,        /* Write protect the upper 1/32 part */+	MV_WP_UPR_1OF16,        /* Write protect the upper 1/16 part */+	MV_WP_UPR_1OF8,         /* Write protect the upper 1/8 part */+	MV_WP_UPR_1OF4,         /* Write protect the upper 1/4 part */+	MV_WP_UPR_1OF2,         /* Write protect the upper 1/2 part */+	MV_WP_ALL               /* Write protect the whole chip */+} MV_SFLASH_WP_REGION;++/* Type Definitions */+typedef struct+{+    MV_U8   opcdWREN;       /* Write enable opcode */+    MV_U8   opcdWRDI;       /* Write disable opcode */+    MV_U8   opcdRDID;       /* Read ID opcode */+    MV_U8   opcdRDSR;       /* Read Status Register opcode */+    MV_U8   opcdWRSR;       /* Write Status register opcode */+    MV_U8   opcdREAD;       /* Read opcode */+    MV_U8   opcdFSTRD;      /* Fast Read opcode */+    MV_U8   opcdPP;         /* Page program opcode */+    MV_U8   opcdSE;         /* Sector erase opcode */+    MV_U8   opcdBE;         /* Bulk erase opcode */+    MV_U8   opcdRES;        /* Read electronic signature */+    MV_U8   opcdPwrSave;    /* Go into power save mode */+    MV_U32  sectorSize;     /* Size of each sector */+    MV_U32  sectorNumber;   /* Number of sectors */+    MV_U32  pageSize;       /* size of each page */+    const char * deviceModel;    /* string with the device model */+    MV_U32  manufacturerId; /* The manufacturer ID */+    MV_U32  deviceId;       /* Device ID */+    MV_U32  spiMaxFreq;     /* The MAX frequency that can be used with the device */+    MV_U32  spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */+    MV_U32  spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */+} MV_SFLASH_DEVICE_PARAMS;++typedef struct+{+    MV_U32					baseAddr;       /* Flash Base Address used in fast mode */+	MV_U8	                manufacturerId;	/* Manufacturer ID */+    MV_U16	                deviceId;	    /* Device ID */+    MV_U32                  sectorSize;     /* Size of each sector - all the same */+    MV_U32                  sectorNumber;   /* Number of sectors */+    MV_U32                  pageSize;       /* Page size - affect allignment */+    MV_U32                  index;          /* index of the device in the sflash table (internal parameter) */+} MV_SFLASH_INFO;++/* Function Prototypes */+/* Init */+MV_STATUS	mvSFlashInit		(MV_SFLASH_INFO * pFlinfo);++/* erase */+MV_STATUS 	mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);+MV_STATUS 	mvSFlashChipErase   (MV_SFLASH_INFO * pFlinfo);++/* Read */+MV_STATUS	mvSFlashBlockRd  	(MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+							     MV_U8* pReadBuff, MV_U32 buffSize);+MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+							     MV_U8* pReadBuff, MV_U32 buffSize);++/* write regardless of the page boundaries and size limit per Page program command */+MV_STATUS	mvSFlashBlockWr		(MV_SFLASH_INFO * pFlinfo, MV_U32 offset,+							     MV_U8* pWriteBuff, MV_U32 buffSize);+/* Get IDs */+MV_STATUS 	mvSFlashIdGet      	(MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);++/* Set and Get the Write Protection region - if the Status register is not locked */+MV_STATUS   mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);+MV_STATUS   mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);++/* Lock the status register for writing - W/Vpp pin should be low to take effect */+MV_STATUS   mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);++/* Get the regions sizes */+MV_U32      mvSFlashSizeGet     (MV_SFLASH_INFO * pFlinfo);++/* Cause the falsh device to go into power save mode */+MV_STATUS   mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);+MV_STATUS   mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);++/* Retreive the string with the device manufacturer and model */+const MV_8 *     mvSFlashModelGet    (MV_SFLASH_INFO * pFlinfo);++#endif /* __INCmvSFlashH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h	2010-11-09 20:28:11.981246772 +0100@@ -0,0 +1,233 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSFlashSpecH+#define __INCmvSFlashSpecH++/* Constants */+#define		MV_SFLASH_READ_CMND_LENGTH		    4		/* 1B opcode + 3B address */+#define		MV_SFLASH_SE_CMND_LENGTH		    4		/* 1B opcode + 3B address */+#define		MV_SFLASH_BE_CMND_LENGTH		    1		/* 1B opcode */+#define		MV_SFLASH_PP_CMND_LENGTH		    4		/* 1B opcode + 3B address */+#define		MV_SFLASH_WREN_CMND_LENGTH		    1		/* 1B opcode */+#define		MV_SFLASH_WRDI_CMND_LENGTH		    1		/* 1B opcode */+#define		MV_SFLASH_RDID_CMND_LENGTH		    1		/* 1B opcode */+#define		MV_SFLASH_RDID_REPLY_LENGTH		    3		/* 1B manf ID and 2B device ID */+#define		MV_SFLASH_RDSR_CMND_LENGTH		    1		/* 1B opcode */+#define		MV_SFLASH_RDSR_REPLY_LENGTH		    1		/* 1B status */+#define		MV_SFLASH_WRSR_CMND_LENGTH		    2		/* 1B opcode + 1B status value */+#define		MV_SFLASH_DP_CMND_LENGTH		    1		/* 1B opcode */+#define		MV_SFLASH_RES_CMND_LENGTH		    1		/* 1B opcode */++/* Status Register Bit Masks */+#define		MV_SFLASH_STATUS_REG_WIP_OFFSET	    0	    /* bit 0; write in progress */+#define		MV_SFLASH_STATUS_REG_WP_OFFSET	    2       /* bit 2-4; write protect option */+#define		MV_SFLASH_STATUS_REG_SRWD_OFFSET	7	    /* bit 7; lock status register write */+#define		MV_SFLASH_STATUS_REG_WIP_MASK	    (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)+#define		MV_SFLASH_STATUS_REG_SRWD_MASK	    (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)++#define		MV_SFLASH_MAX_WAIT_LOOP			    1000000+#define     MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP  0x50000000++#define		MV_SFLASH_DEFAULT_RDID_OPCD		    0x9F	/* Default Read ID */+#define     MV_SFLASH_DEFAULT_WREN_OPCD         0x06	/* Default Write Enable */+#define     MV_SFLASH_NO_SPECIFIC_OPCD          0x00++/********************************/+/*  ST M25Pxxx Device Specific  */+/********************************/++/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */+#define     MV_M25PXXX_ST_MANF_ID               0x20+#define     MV_M25P32_DEVICE_ID                 0x2016+#define     MV_M25P32_MAX_SPI_FREQ              20000000    /* 20MHz */+#define     MV_M25P32_MAX_FAST_SPI_FREQ         50000000    /* 50MHz */+#define     MV_M25P32_FAST_READ_DUMMY_BYTES     1+#define     MV_M25P64_DEVICE_ID                 0x2017+#define     MV_M25P64_MAX_SPI_FREQ              20000000    /* 20MHz */+#define     MV_M25P64_MAX_FAST_SPI_FREQ         50000000    /* 50MHz */+#define     MV_M25P64_FAST_READ_DUMMY_BYTES     1+#define     MV_M25P128_DEVICE_ID                0x2018+#define     MV_M25P128_MAX_SPI_FREQ             20000000    /* 20MHz */+#define     MV_M25P128_MAX_FAST_SPI_FREQ        50000000    /* 50MHz */+#define     MV_M25P128_FAST_READ_DUMMY_BYTES    1+++/* Sector Sizes and population per device model*/+#define     MV_M25P32_SECTOR_SIZE               0x10000 /* 64K */+#define     MV_M25P64_SECTOR_SIZE               0x10000 /* 64K */+#define     MV_M25P128_SECTOR_SIZE              0x40000 /* 256K */+#define     MV_M25P32_SECTOR_NUMBER             64+#define     MV_M25P64_SECTOR_NUMBER             128+#define     MV_M25P128_SECTOR_NUMBER            64+#define		MV_M25P_PAGE_SIZE				    0x100   /* 256 byte */++#define		MV_M25P_WREN_CMND_OPCD			    0x06	/* Write Enable */+#define		MV_M25P_WRDI_CMND_OPCD			    0x04	/* Write Disable */+#define		MV_M25P_RDID_CMND_OPCD			    0x9F	/* Read ID */+#define		MV_M25P_RDSR_CMND_OPCD			    0x05	/* Read Status Register */+#define		MV_M25P_WRSR_CMND_OPCD			    0x01	/* Write Status Register */+#define		MV_M25P_READ_CMND_OPCD			    0x03	/* Sequential Read */+#define		MV_M25P_FAST_RD_CMND_OPCD		    0x0B	/* Fast Read */+#define		MV_M25P_PP_CMND_OPCD			    0x02	/* Page Program */+#define		MV_M25P_SE_CMND_OPCD			    0xD8	/* Sector Erase */+#define		MV_M25P_BE_CMND_OPCD			    0xC7	/* Bulk Erase */+#define		MV_M25P_RES_CMND_OPCD			    0xAB	/* Read Electronic Signature */++/* Status Register Write Protect Bit Masks - 3bits */+#define		MV_M25P_STATUS_REG_WP_MASK	        (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_NONE              (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_1_OF_64           (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_1_OF_32           (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_1_OF_16           (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_1_OF_8            (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_1_OF_4            (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_1_OF_2            (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_M25P_STATUS_BP_ALL               (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)++/************************************/+/*  MXIC MX25L6405 Device Specific  */+/************************************/++/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */+#define     MV_MXIC_MANF_ID                     0xC2+#define     MV_MX25L6405_DEVICE_ID              0x2017+#define     MV_MX25L6405_MAX_SPI_FREQ           20000000    /* 20MHz */+#define     MV_MX25L6405_MAX_FAST_SPI_FREQ      50000000    /* 50MHz */+#define     MV_MX25L6405_FAST_READ_DUMMY_BYTES  1+#define     MV_MXIC_DP_EXIT_DELAY               30          /* 30 ms */++/* Sector Sizes and population per device model*/+#define     MV_MX25L6405_SECTOR_SIZE            0x10000 /* 64K */+#define     MV_MX25L6405_SECTOR_NUMBER          128+#define		MV_MXIC_PAGE_SIZE			        0x100   /* 256 byte */++#define		MV_MX25L_WREN_CMND_OPCD			    0x06	/* Write Enable */+#define		MV_MX25L_WRDI_CMND_OPCD			    0x04	/* Write Disable */+#define		MV_MX25L_RDID_CMND_OPCD			    0x9F	/* Read ID */+#define		MV_MX25L_RDSR_CMND_OPCD			    0x05	/* Read Status Register */+#define		MV_MX25L_WRSR_CMND_OPCD			    0x01	/* Write Status Register */+#define		MV_MX25L_READ_CMND_OPCD			    0x03	/* Sequential Read */+#define		MV_MX25L_FAST_RD_CMND_OPCD		    0x0B	/* Fast Read */+#define		MV_MX25L_PP_CMND_OPCD			    0x02	/* Page Program */+#define		MV_MX25L_SE_CMND_OPCD			    0xD8	/* Sector Erase */+#define		MV_MX25L_BE_CMND_OPCD			    0xC7	/* Bulk Erase */+#define     MV_MX25L_DP_CMND_OPCD               0xB9    /* Deep Power Down */+#define		MV_MX25L_RES_CMND_OPCD			    0xAB	/* Read Electronic Signature */++/* Status Register Write Protect Bit Masks - 4bits */+#define		MV_MX25L_STATUS_REG_WP_MASK	        (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_NONE             (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_128         (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_64          (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_32          (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_16          (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_8           (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_4           (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_1_OF_2           (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     MV_MX25L_STATUS_BP_ALL              (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)++/************************************/+/*  SPANSION S25FL128P Device Specific  */+/************************************/++/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */+#define     MV_SPANSION_MANF_ID                     	0x01+#define     MV_S25FL128_DEVICE_ID              		0x2018+#define     MV_S25FL128_MAX_SPI_FREQ           		33000000    /* 33MHz */+#define     MV_S25FL128_MAX_FAST_SPI_FREQ        	104000000    /* 104MHz */+#define     MV_S25FL128_FAST_READ_DUMMY_BYTES    	1++/* Sector Sizes and population per device model*/+#define     MV_S25FL128_SECTOR_SIZE            			0x40000 /* 256K */+#define     MV_S25FL128_SECTOR_NUMBER          			64+#define	    MV_S25FL_PAGE_SIZE			        	0x100   /* 256 byte */++#define		MV_S25FL_WREN_CMND_OPCD			    0x06	/* Write Enable */+#define		MV_S25FL_WRDI_CMND_OPCD			    0x04	/* Write Disable */+#define		MV_S25FL_RDID_CMND_OPCD			    0x9F	/* Read ID */+#define		MV_S25FL_RDSR_CMND_OPCD			    0x05	/* Read Status Register */+#define		MV_S25FL_WRSR_CMND_OPCD			    0x01	/* Write Status Register */+#define		MV_S25FL_READ_CMND_OPCD			    0x03	/* Sequential Read */+#define		MV_S25FL_FAST_RD_CMND_OPCD		    0x0B	/* Fast Read */+#define		MV_S25FL_PP_CMND_OPCD			    0x02	/* Page Program */+#define		MV_S25FL_SE_CMND_OPCD			    0xD8	/* Sector Erase */+#define		MV_S25FL_BE_CMND_OPCD			    0xC7	/* Bulk Erase */+#define     	MV_S25FL_DP_CMND_OPCD               	    0xB9    	/* Deep Power Down */+#define		MV_S25FL_RES_CMND_OPCD			    0xAB	/* Read Electronic Signature */++/* Status Register Write Protect Bit Masks - 4bits */+#define		MV_S25FL_STATUS_REG_WP_MASK	        (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_NONE             	(0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_128         	(0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_64          	(0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_32          	(0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_16          	(0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_8           	(0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_4           	(0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_1_OF_2           	(0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)+#define     	MV_S25FL_STATUS_BP_ALL              	(0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)++#endif /* __INCmvSFlashSpecH */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c	2010-11-09 20:28:12.022495595 +0100@@ -0,0 +1,576 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "spi/mvSpi.h"+#include "spi/mvSpiSpec.h"++#include "ctrlEnv/mvCtrlEnvLib.h"++/* #define MV_DEBUG */+#ifdef MV_DEBUG+#define DB(x) x+#define mvOsPrintf printf+#else+#define DB(x)+#endif+++/*******************************************************************************+* mvSpi16bitDataTxRx - Transmt and receive data+*+* DESCRIPTION:+*       Tx data and block waiting for data to be transmitted+*+********************************************************************************/+static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)+{+    MV_U32 i;+    MV_BOOL ready = MV_FALSE;++    /* First clear the bit in the interrupt cause register */+    MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);++    /* Transmit data */+    MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));++    /* wait with timeout for memory ready */+    for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)+    {+        if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))+        {+            ready = MV_TRUE;+            break;+        }+#ifdef MV_SPI_SLEEP_ON_WAIT+        mvOsSleep(1);+#endif /* MV_SPI_SLEEP_ON_WAIT */+    }++    if (!ready)+        return MV_TIMEOUT;++    /* check that the RX data is needed */+    if (pRxData)+    {+    	if ((MV_U32)pRxData &  0x1) /* check if address is not alligned to 16bit */+    	{+#if defined(MV_CPU_LE)+    		/* perform the data write to the buffer in two stages with 8bit each */+    		MV_U8 * bptr = (MV_U8*)pRxData;+    		MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));+    		*bptr = (data & 0xFF);+    		++bptr;+    		*bptr = ((data >> 8) & 0xFF);++#elif defined(MV_CPU_BE)++    		/* perform the data write to the buffer in two stages with 8bit each */+    		MV_U8 * bptr = (MV_U8 *)pRxData;+    		MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));+    		*bptr = ((data >> 8) & 0xFF);+    		++bptr;+    		*bptr = (data & 0xFF);++#else+    #error "CPU endianess isn't defined!\n"+#endif++    	}+    	else+        	*pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));+    }++    return MV_OK;+}+++/*******************************************************************************+* mvSpi8bitDataTxRx - Transmt and receive data (8bits)+*+* DESCRIPTION:+*       Tx data and block waiting for data to be transmitted+*+********************************************************************************/+static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)+{+    MV_U32 i;+    MV_BOOL ready = MV_FALSE;++    /* First clear the bit in the interrupt cause register */+    MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);++    /* Transmit data */+    MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);++    /* wait with timeout for memory ready */+    for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)+    {+        if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))+        {+            ready = MV_TRUE;+            break;+        }+#ifdef MV_SPI_SLEEP_ON_WAIT+        mvOsSleep(1);+#endif /* MV_SPI_SLEEP_ON_WAIT */+    }++    if (!ready)+        return MV_TIMEOUT;++    /* check that the RX data is needed */+    if (pRxData)+    	*pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);++    return MV_OK;+}++/*+#####################################################################################+#####################################################################################+*/++/*******************************************************************************+* mvSpiInit - Initialize the SPI controller+*+* DESCRIPTION:+*       Perform the neccessary initialization in order to be able to send an+*		receive over the SPI interface.+*+* INPUT:+*       serialBaudRate: Baud rate (SPI clock frequency)+*		use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)+*+* OUTPUT:+*       None.+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiInit	(MV_U32 serialBaudRate)+{+    MV_STATUS ret;++    /* Set the serial clock */+    if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)+        return ret;++    /* For devices in which the SPI is muxed on the MPP with other interfaces*/+    mvMPPConfigToSPI();++	/* Configure the default SPI mode to be 16bit */+	MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* Fix ac timing on SPI in 6183, 6183L and 78x00 only */+	if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||+		 (mvCtrlModelGet() == MV_6183L_DEV_ID) ||+		(mvCtrlModelGet() == MV_78100_DEV_ID) ||+		(mvCtrlModelGet() == MV_78200_DEV_ID) ||+		(mvCtrlModelGet() == MV_76100_DEV_ID))+	    MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);++    /* Verify that the CS is deasserted */+    mvSpiCsDeassert();++    return MV_OK;+}++/*******************************************************************************+* mvSpiBaudRateSet - Set the Frequency of the SPI clock+*+* DESCRIPTION:+*       Set the Prescale bits to adapt to the requested baud rate (the clock+*       used for thr SPI).+*+* INPUT:+*       serialBaudRate: Baud rate (SPI clock frequency)+*+* OUTPUT:+*       None.+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)+{+    MV_U8 i;+	/* MV_U8 preScale[32] = {1, 1, 2, 3, 4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,+						  2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};+	*/+	MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};+	MV_U8 bestPrescaleIndx = 100;+	MV_U32 minBaudOffset = 0xFFFFFFFF;+	MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/+	MV_U32 tempReg;++	/* Find the best prescale configuration - less or equal */+	for (i=0; i<14; i++)+	{+		/* check for higher - irrelevent */+		if ((cpuClk / preScale[i]) > serialBaudRate)+			continue;++		/* check for exact fit */+		if ((cpuClk / preScale[i]) == serialBaudRate)+		{+			bestPrescaleIndx = i;+			break;+		}++		/* check if this is better than the previous one */+		if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)+		{+			minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));+			bestPrescaleIndx = i;+		}+	}++	if (bestPrescaleIndx > 14)+    {+        mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);+		return MV_OUT_OF_RANGE;+    }++	/* configure the Prescale */+	tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);+	tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));+	MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);++    return MV_OK;+}++/*******************************************************************************+* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer+*+* DESCRIPTION:+*       Assert The chip select - used to select an external SPI device+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Success or Error code.+*+********************************************************************************/+MV_VOID mvSpiCsAssert(MV_VOID)+{+    /* For devices in which the SPI is muxed on the MPP with other interfaces*/+    mvMPPConfigToSPI();+    mvOsUDelay(1);+    MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);+}++/*******************************************************************************+* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a+*				  SPI transfer sequence+*+* DESCRIPTION:+*       DeAssert the chip select pin+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       Success or Error code.+*+********************************************************************************/+MV_VOID mvSpiCsDeassert(MV_VOID)+{+	MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);++    /* For devices in which the SPI is muxed on the MPP with other interfaces*/+    mvMPPConfigToDefault();+}++/*******************************************************************************+* mvSpiRead - Read a buffer over the SPI interface+*+* DESCRIPTION:+*       Receive (read) a buffer over the SPI interface in 16bit chunks. If the+*		buffer size is odd, then the last chunk will be 8bits. Chip select is not+*       handled at this level.+*+* INPUT:+*		pRxBuff: Pointer to the buffer to hold the received data+*		buffSize: length of the pRxBuff+*+* OUTPUT:+*		pRxBuff: Pointer to the buffer with the received data+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiRead	(MV_U8* pRxBuff, MV_U32 buffSize)+{+    MV_STATUS ret;+	MV_U32 bytesLeft = buffSize;+	MV_U16* rxPtr = (MV_U16*)pRxBuff;++    /* check for null parameters */+    if (pRxBuff == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Check that the buffer pointer and the buffer size are 16bit aligned */+    if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))+    {+	/* Verify that the SPI mode is in 16bit mode */+	MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* TX/RX as long we have complete 16bit chunks */+	while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)+	{+		/* Transmitted and wait for the transfer to be completed */+		if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)+			return ret;++		/* increment the pointers */+		rxPtr++;+		bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;+	}++    }+    else+    {+	/* Verify that the SPI mode is in 8bit mode */+	MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* TX/RX in 8bit chanks */+	while (bytesLeft > 0)+	{+        	/* Transmitted and wait for the transfer to be completed */+		if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)+			return ret;+		/* increment the pointers */+		pRxBuff++;+		bytesLeft--;+	}+    }++	return MV_OK;+}++/*******************************************************************************+* mvSpiWrite - Transmit a buffer over the SPI interface+*+* DESCRIPTION:+*       Transmit a buffer over the SPI interface in 16bit chunks. If the+*		buffer size is odd, then the last chunk will be 8bits. No chip select+*       action is taken.+*+* INPUT:+*		pTxBuff: Pointer to the buffer holding the TX data+*		buffSize: length of the pTxBuff+*+* OUTPUT:+*       None.+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)+{+    MV_STATUS ret;+	MV_U32 bytesLeft = buffSize;+	MV_U16* txPtr = (MV_U16*)pTxBuff;++    /* check for null parameters */+    if (pTxBuff == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Check that the buffer pointer and the buffer size are 16bit aligned */+    if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))+    {+	/* Verify that the SPI mode is in 16bit mode */+	MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* TX/RX as long we have complete 16bit chunks */+	while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)+	{+        /* Transmitted and wait for the transfer to be completed */+		if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)+			return ret;++		/* increment the pointers */+		txPtr++;+		bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;+	}+    }+    else+    {++	/* Verify that the SPI mode is in 8bit mode */+	MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* TX/RX in 8bit chanks */+	while (bytesLeft > 0)+	{+		/* Transmitted and wait for the transfer to be completed */+		if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)+			return ret;++		/* increment the pointers */+		pTxBuff++;+		bytesLeft--;+	}+    }++	return MV_OK;+}+++/*******************************************************************************+* mvSpiReadWrite - Read and Write a buffer simultanuosely+*+* DESCRIPTION:+*       Transmit and receive a buffer over the SPI in 16bit chunks. If the+*		buffer size is odd, then the last chunk will be 8bits. The SPI chip+*       select is not handled implicitely.+*+* INPUT:+*       pRxBuff: Pointer to the buffer to write the RX info in+*		pTxBuff: Pointer to the buffer holding the TX info+*		buffSize: length of both the pTxBuff and pRxBuff+*+* OUTPUT:+*       pRxBuff: Pointer of the buffer holding the RX data+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)+{+    MV_STATUS ret;+    MV_U32 bytesLeft = buffSize;+    MV_U16* txPtr = (MV_U16*)pTxBuff;+    MV_U16* rxPtr = (MV_U16*)pRxBuff;++    /* check for null parameters */+    if ((pRxBuff == NULL) || (pTxBuff == NULL))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++    /* Check that the buffer pointer and the buffer size are 16bit aligned */+    if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))+    {+	/* Verify that the SPI mode is in 16bit mode */+	MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* TX/RX as long we have complete 16bit chunks */+	while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)+	{+        /* Transmitted and wait for the transfer to be completed */+		if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)+			return ret;++		/* increment the pointers */+		txPtr++;+		rxPtr++;+		bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;+	}+    }+    else+    {+	/* Verify that the SPI mode is in 8bit mode */+	MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);++	/* TX/RX in 8bit chanks */+	while (bytesLeft > 0)+	{+		/* Transmitted and wait for the transfer to be completed */+		if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)+			return ret;+		pRxBuff++;+		pTxBuff++;+		bytesLeft--;+	}+    }++	return MV_OK;+}++diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c	2010-11-09 20:28:12.052495353 +0100@@ -0,0 +1,249 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#include "spi/mvSpi.h"+#include "spi/mvSpiSpec.h"++/*#define MV_DEBUG*/+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif+++/*******************************************************************************+* mvSpiReadAndWrite - Read and Write a buffer simultanuousely+*+* DESCRIPTION:+*       Transmit and receive a buffer over the SPI in 16bit chunks. If the+*		buffer size is odd, then the last chunk will be 8bits.+*+* INPUT:+*       pRxBuff: Pointer to the buffer to write the RX info in+*		pTxBuff: Pointer to the buffer holding the TX info+*		buffSize: length of both the pTxBuff and pRxBuff+*+* OUTPUT:+*       pRxBuff: Pointer of the buffer holding the RX data+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)+{+    MV_STATUS ret;++    /* check for null parameters */+    if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++	/* First assert the chip select */+	mvSpiCsAssert();++    ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);++	/* Finally deassert the chip select */+	mvSpiCsDeassert();++	return ret;+}++/*******************************************************************************+* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line+*+* DESCRIPTION:+*       Assert the chip select line. Transmit the command buffer followed by+*       the data buffer. Then deassert the CS line.+*+* INPUT:+*       pCmndBuff: Pointer to the command buffer to transmit+*       cmndSize: length of the command size+*		pTxDataBuff: Pointer to the data buffer to transmit+*		txDataSize: length of the data buffer+*+* OUTPUT:+*       None.+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS	mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,+                                 MV_U32 txDataSize)+{+    MV_STATUS ret = MV_OK, tempRet;++    /* check for null parameters */+#ifndef CONFIG_MARVELL+    if(NULL == pTxDataBuff)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }+#endif++    if (pCmndBuff == NULL)+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++	/* First assert the chip select */+	mvSpiCsAssert();++    /* first write the command */+    if ((cmndSize) && (pCmndBuff != NULL))+    {+        if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)+            ret = tempRet;+    }++    /* Then write the data buffer */+#ifndef CONFIG_MARVELL+    if (txDataSize)+#else+    if ((txDataSize) && (pTxDataBuff != NULL))+#endif+    {+        if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)+            ret = tempRet;+    }++	/* Finally deassert the chip select */+	mvSpiCsDeassert();++	return ret;+}++/*******************************************************************************+* mvSpiWriteThenRead - Serialize a command then read a data buffer+*+* DESCRIPTION:+*       Assert the chip select line. Transmit the command buffer then read+*       the data buffer. Then deassert the CS line.+*+* INPUT:+*       pCmndBuff: Pointer to the command buffer to transmit+*       cmndSize: length of the command size+*		pRxDataBuff: Pointer to the buffer to read the data in+*		txDataSize: length of the data buffer+*+* OUTPUT:+*		pRxDataBuff: Pointer to the buffer holding the data+*+* RETURN:+*       Success or Error code.+*+*+*******************************************************************************/+MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,+                              MV_U32 rxDataSize,MV_U32 dummyBytesToRead)+{+    MV_STATUS ret = MV_OK, tempRet;+    MV_U8   dummyByte;++    /* check for null parameters */+    if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))+    {+        mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);+        return MV_BAD_PARAM;+    }++	/* First assert the chip select */+	mvSpiCsAssert();++    /* first write the command */+    if ((cmndSize) && (pCmndBuff != NULL))+    {+        if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)+            ret = tempRet;+    }++    /* Read dummy bytes before real data.   */+    while(dummyBytesToRead)+    {+        mvSpiRead(&dummyByte,1);+        dummyBytesToRead--;+    }++    /* Then write the data buffer */+    if ((rxDataSize) && (pRxDataBuff != NULL))+    {+        if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)+            ret = tempRet;+    }++	/* Finally deassert the chip select */+	mvSpiCsDeassert();++	return ret;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h	2010-11-09 20:28:12.082495364 +0100@@ -0,0 +1,82 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSpiCmndhH+#define __INCmvSpiCmndhH++#include "mvTypes.h"++/* Function Prototypes */++/* Simultanuous Read and write */+MV_STATUS	mvSpiReadAndWrite	(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);++/* write command - write a command and then write data */+MV_STATUS	mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);++/* read command - write a command and then read data by writing dummy data */+MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,+                              MV_U32 rxDataSize,MV_U32 dummyBytesToRead);++#endif /* __INCmvSpiCmndhH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h	2010-11-09 20:28:12.121243940 +0100@@ -0,0 +1,94 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSpihH+#define __INCmvSpihH++#include "mvCommon.h"+#include "mvOs.h"+#include "ctrlEnv/mvCtrlEnvSpec.h"++/* Function Prototypes */+/* Init */+MV_STATUS   mvSpiInit		(MV_U32 serialBaudRate);++/* Set the Frequency of the Spi clock */+MV_STATUS   mvSpiBaudRateSet(MV_U32 serialBaudRate);++/* Assert the SPI chip select */+MV_VOID     mvSpiCsAssert   (MV_VOID);++/* De-assert the SPI chip select */+MV_VOID     mvSpiCsDeassert (MV_VOID);++/* Simultanuous Read and write */+MV_STATUS	mvSpiReadWrite	(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);++/* serialize a buffer on the TX line - Rx is ignored */+MV_STATUS	mvSpiWrite  	(MV_U8* pTxBuff, MV_U32 buffSize);++/* read from the RX line by writing dummy values to the TX line */+MV_STATUS	mvSpiRead   	(MV_U8* pRxBuff, MV_U32 buffSize);++#endif /* __INCmvSpihH */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h	2010-11-09 20:28:12.162495430 +0100@@ -0,0 +1,98 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/++#ifndef __INCmvSpiSpecH+#define __INCmvSpiSpecH++/* Constants */+#define		MV_SPI_WAIT_RDY_MAX_LOOP			100000+#define		MV_SPI_16_BIT_CHUNK_SIZE			2+#define		MV_SPI_DUMMY_WRITE_16BITS			0xFFFF+#define		MV_SPI_DUMMY_WRITE_8BITS			0xFF++/* Marvell Flash Device Controller Registers */+#define		MV_SPI_CTRLR_OFST					0x10600+#define		MV_SPI_IF_CTRL_REG					(MV_SPI_CTRLR_OFST + 0x00)+#define		MV_SPI_IF_CONFIG_REG				(MV_SPI_CTRLR_OFST + 0x04)+#define		MV_SPI_DATA_OUT_REG					(MV_SPI_CTRLR_OFST + 0x08)+#define		MV_SPI_DATA_IN_REG					(MV_SPI_CTRLR_OFST + 0x0c)+#define		MV_SPI_INT_CAUSE_REG				(MV_SPI_CTRLR_OFST + 0x10)+#define		MV_SPI_INT_CAUSE_MASK_REG			(MV_SPI_CTRLR_OFST + 0x14)++/* Serial Memory Interface Control Register Masks */+#define		MV_SPI_CS_ENABLE_OFFSET				0		/* bit 0 */+#define		MV_SPI_MEMORY_READY_OFFSET			1		/* bit 1 */+#define		MV_SPI_CS_ENABLE_MASK				(0x1  << MV_SPI_CS_ENABLE_OFFSET)+#define		MV_SPI_MEMORY_READY_MASK			(0x1  << MV_SPI_MEMORY_READY_OFFSET)++/* Serial Memory Interface Configuration Register Masks */+#define		MV_SPI_CLK_PRESCALE_OFFSET			0		/* bit 0-4 */+#define		MV_SPI_BYTE_LENGTH_OFFSET			5		/* bit 5 */+#define		MV_SPI_ADDRESS_BURST_LENGTH_OFFSET  8	    /* bit 8-9 */+#define		MV_SPI_CLK_PRESCALE_MASK			(0x1F << MV_SPI_CLK_PRESCALE_OFFSET)+#define		MV_SPI_BYTE_LENGTH_MASK				(0x1  << MV_SPI_BYTE_LENGTH_OFFSET)+#define		MV_SPI_ADDRESS_BURST_LENGTH_MASK	(0x3  << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)++#endif /* __INCmvSpiSpecH */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c	2010-11-09 20:28:12.192495512 +0100@@ -0,0 +1,1023 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell+International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File in accordance with the terms and conditions of the General+Public License Version 2, June 1991 (the "GPL License"), a copy of which is+available along with the File in the license.txt file or by writing to the Free+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY+DISCLAIMED.  The GPL License provides additional details about this warranty+disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or+modify this File under the following licensing terms.+Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer.++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution.++    *   Neither the name of Marvell nor the names of its contributors may be+        used to endorse or promote products derived from this software without+        specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+++#include "mvTwsi.h"+#include "mvTwsiSpec.h"+#include "cpu/mvCpu.h"+++/*#define MV_DEBUG*/+#ifdef MV_DEBUG+#define DB(x) x+#else+#define DB(x)+#endif++static MV_VOID twsiIntFlgClr(MV_U8 chanNum);+static MV_BOOL twsiMainIntGet(MV_U8 chanNum);+static MV_VOID twsiAckBitSet(MV_U8 chanNum);+static MV_U32 twsiStsGet(MV_U8 chanNum);+static MV_VOID twsiReset(MV_U8 chanNum);+static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);+static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);+static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);+static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);+static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);+++static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)+{+	if(timeout >= TWSI_TIMEOUT_VALUE)+	{+		DB(mvOsPrintf("%s",pString));+		return MV_TRUE;+	}+	return MV_FALSE;+	+}+/*******************************************************************************+* mvTwsiStartBitSet - Set start bit on the bus+*+* DESCRIPTION:+*       This routine sets the start bit on the TWSI bus. +*       The routine first checks for interrupt flag condition, then it sets +*       the start bit  in the TWSI Control register. +*       If the interrupt flag condition check previously was set, the function +*       will clear it.+*       The function then wait for the start bit to be cleared by the HW. +*       Then it waits for the interrupt flag to be set and eventually, the +*       TWSI status is checked to be 0x8 or 0x10(repeated start bit).+*+* INPUT:+*       chanNum - TWSI channel.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK is start bit was set successfuly on the bus.+*       MV_FAIL if interrupt flag was set before setting start bit.+*+*******************************************************************************/+MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)+{+	MV_BOOL isIntFlag = MV_FALSE;+	MV_U32 timeout, temp;++	DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));+	/* check Int flag */+    	if(twsiMainIntGet(chanNum))+		isIntFlag = MV_TRUE;+	/* set start Bit */+    	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));+	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);+	+	/* in case that the int flag was set before i.e. repeated start bit */+	if(isIntFlag){+		DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));+		twsiIntFlgClr(chanNum);+	}+	+   	/* wait for interrupt */+	timeout = 0;+	while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));+	+	/* check for timeout */	+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))+		return MV_TIMEOUT;+++	/* check that start bit went down */+	if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)+	{+		mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");+		return MV_FAIL;+	}	++	/* check the status */+	temp = twsiStsGet(chanNum);+	if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))+	  {+		mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);+		return MV_FAIL;+	}++	return MV_OK;	++}++/*******************************************************************************+* mvTwsiStopBitSet - Set stop bit on the bus+*+* DESCRIPTION:+*       This routine set the stop bit on the TWSI bus. +*       The function then wait for the stop bit to be cleared by the HW. +*       Finally the function checks for status of 0xF8.+*+* INPUT:+*	chanNum - TWSI channel+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE is stop bit was set successfuly on the bus.+*+*******************************************************************************/+MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)+{+    	MV_U32	timeout, temp;++    	/* Generate stop bit */+	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));+    	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);++	twsiIntFlgClr(chanNum);+		+   	/* wait for stop bit to come down */+	timeout = 0;+	while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));++	/* check for timeout */+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))+		return MV_TIMEOUT;+	+	/* check that the stop bit went down */+	if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)	+	{+		mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");+		return MV_FAIL;+	}+	+	/* check the status */+	temp = twsiStsGet(chanNum);+	if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){+		mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);+		return MV_FAIL;+	}++	return MV_OK;+}++/*******************************************************************************+* twsiMainIntGet - Get twsi bit from main Interrupt cause.+*+* DESCRIPTION:+*       This routine returns the twsi interrupt flag value.+*       +* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_TRUE is interrupt flag is set, MV_FALSE otherwise.+*+*******************************************************************************/+static MV_BOOL twsiMainIntGet(MV_U8 chanNum)+{+	MV_U32 temp;+	+	/* get the int flag bit */++	temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);+	if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))+	    return MV_TRUE;+    +	return MV_FALSE;+}+/*******************************************************************************+* twsiIntFlgClr - Clear Interrupt flag.+*+* DESCRIPTION:+*       This routine clears the interrupt flag. It does NOT poll the interrupt+*       to make sure the clear. After clearing the interrupt, it waits for at +*       least 1 miliseconds.+*+* INPUT:+*	chanNum - TWSI channel+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+static MV_VOID twsiIntFlgClr(MV_U8 chanNum)+{+	MV_U32 temp;++	/* wait for 1 mili to prevent TWSI register write after write problems */+   	mvOsDelay(1);+	/* clear the int flag bit */+	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));+    	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));++	/* wait for 1 mili sec for the clear to take effect */+   	mvOsDelay(1);+	+	return;+}+++/*******************************************************************************+* twsiAckBitSet - Set acknowledge bit on the bus+*+* DESCRIPTION:+*       This routine set the acknowledge bit on the TWSI bus.+*+* INPUT:+*       None.+*+* OUTPUT:+*       None.+*+* RETURN:+*       None.+*+*******************************************************************************/+static MV_VOID twsiAckBitSet(MV_U8 chanNum)+{+	MV_U32 temp;++	/*Set the Ack bit */+	temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));+    	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);++	/* Add delay of 1ms */+	mvOsDelay(1);+	return;+}+++/*******************************************************************************+* twsiInit - Initialize TWSI interface+*+* DESCRIPTION:+*       This routine:+*	-Reset the TWSI.+*	-Initialize the TWSI clock baud rate according to given frequancy+*	 parameter based on Tclk frequancy and enables TWSI slave.+*       -Set the ack bit.+*	-Assign the TWSI slave address according to the TWSI address Type.+*       +*+* INPUT:+*	chanNum - TWSI channel+*       frequancy - TWSI frequancy in KHz. (up to 100KHZ)+*+* OUTPUT:+*       None.+*+* RETURN:+*       Actual frequancy.+*+*******************************************************************************/+MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)+{+    	MV_U32	n,m,freq,margin,minMargin = 0xffffffff;+	MV_U32	power;+    	MV_U32	actualFreq = 0,actualN = 0,actualM = 0,val;++	if(frequancy > 100000)+	{+		mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");+	}++	DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));+    	/* Calucalte N and M for the TWSI clock baud rate */+    	for(n = 0 ; n < 8 ; n++)+    	{+        	for(m = 0 ; m < 16 ; m++)+        	{+            		power = 2 << n; /* power = 2^(n+1) */+            		freq = Tclk/(10*(m+1)*power);+            		margin = MV_ABS(frequancy - freq);+            		if(margin < minMargin)+            		{+                		minMargin   = margin;+                		actualFreq  = freq;+                		actualN     = n;+                		actualM     = m;+            		}+        	}+		}+	DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));+	/* Reset the TWSI logic */+	twsiReset(chanNum);++	/* Set the baud rate */+	val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);+    	MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);++    	/* Enable the TWSI and slave */+	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK); ++	/* set the TWSI slave address */+	if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */+    	{+		/* writing the 2 most significant bits of the 10 bit address*/+		val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );+		/* bits 7:3 must be 0x11110 */+		val |= TWSI_SLAVE_ADDR_10BIT_CONST;+		/* set GCE bit */+		if(generalCallEnable)+			val |= TWSI_SLAVE_ADDR_GCE_ENA;+		/* write slave address */+		MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);++         	/* writing the 8 least significant bits of the 10 bit address*/+        	val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;  +        	MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);+    	}+    	else /*7 bit address*/+    	{+		/* set the 7 Bits address */+        	MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);+		val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;+        	MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);+    	}++	/* unmask twsi int */+    val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));+	MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);+	/* Add delay of 1ms */+	mvOsDelay(1);+	+   return actualFreq;+} +++/*******************************************************************************+* twsiStsGet - Get the TWSI status value.+*+* DESCRIPTION:+*       This routine returns the TWSI status value.+*+* INPUT:+*	chanNum - TWSI channel+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_U32 - the TWSI status.+*+*******************************************************************************/+static MV_U32 twsiStsGet(MV_U8 chanNum)+{+    return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));++}++/*******************************************************************************+* twsiReset - Reset the TWSI.+*+* DESCRIPTION:+*       Resets the TWSI logic and sets all TWSI registers to their reset values.+*+* INPUT:+*      chanNum - TWSI channel+*+* OUTPUT:+*       None.+*+* RETURN:+*       None+*+*******************************************************************************/+static MV_VOID twsiReset(MV_U8 chanNum)+{+    	/* Reset the TWSI logic */+    	MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);++	/* wait for 2 mili sec */+   	mvOsDelay(2);++	return;+}+++++/******************************* POLICY ****************************************/++++/*******************************************************************************+* mvTwsiAddrSet - Set address on TWSI bus.+*+* DESCRIPTION:+*       This function Set address (7 or 10 Bit address) on the Twsi Bus.+*+* INPUT:+*	chanNum - TWSI channel+*       pTwsiAddr - twsi address.+*	command	 - read / write .+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK - if setting the address completed succesfully.+*	MV_FAIL otherwmise.+*+*******************************************************************************/+MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)+{+	DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\+		 			pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));+	/* 10 Bit address */+	if(pTwsiAddr->type == ADDR10_BIT)+	{+		return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);+	}+	/* 7 Bit address */+	else+	{+		return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);+	}++}++/*******************************************************************************+* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.+*+* DESCRIPTION:+*       There are two address phases:+*       1) Write '11110' to data register bits [7:3] and 10-bit address MSB +*          (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit +*          to the Data register. Then it clears interrupt flag which drive +*          the address on the TWSI bus. The function then waits for interrupt +*          flag to be active and status 0x18 (write) or 0x40 (read) to be set.+*       2) write the rest of 10-bit address to data register and clears +*          interrupt flag which drive the address on the TWSI bus. The +*          function then waits for interrupt flag to be active and status +*          0xD0 (write) or 0xE0 (read) to be set. +*+* INPUT:+*	chanNum - TWSI channel+*       deviceAddress - twsi address.+*	command	 - read / write .+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK - if setting the address completed succesfully.+*	MV_FAIL otherwmise.+*+*******************************************************************************/+static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)+{+	MV_U32 val,timeout;++	/* writing the 2 most significant bits of the 10 bit address*/+	val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );+	/* bits 7:3 must be 0x11110 */+	val |= TWSI_DATA_ADDR_10BIT_CONST;+	/* set command */+	val |= command;+	MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);+	/* WA add a delay */+	mvOsDelay(1);++	/* clear Int flag */+	twsiIntFlgClr(chanNum);++	/* wait for Int to be Set */+	timeout = 0;+	while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));++	/* check for timeout */+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))+		return MV_TIMEOUT;+	+	/* check the status */+	val = twsiStsGet(chanNum);+	if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) || +	   ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))+	{+		mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\+						,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );+		return MV_FAIL;+	}++	/* set 	8 LSB of the address */+	val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;+	MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);++	/* clear Int flag */+	twsiIntFlgClr(chanNum);++	/* wait for Int to be Set */+	timeout = 0;+	while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));++	/* check for timeout */+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))+		return MV_TIMEOUT;+	+	/* check the status */+	val = twsiStsGet(chanNum);+	if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) || +	   ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))+	{+		mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\+						,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );+		return MV_FAIL;+	}+	+	return MV_OK;+}++/*******************************************************************************+* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.+*+* DESCRIPTION:+*       This function writes 7 bit address plus a write or read bit to the +*       Data register. Then it clears interrupt flag which drive the address on +*       the TWSI bus. The function then waits for interrupt flag to be active+*       and status 0x18 (write) or 0x40 (read) to be set.+*+* INPUT:+*	chanNum - TWSI channel+*       deviceAddress - twsi address.+*	command	 - read / write .+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK - if setting the address completed succesfully.+*	MV_FAIL otherwmise.+*+*******************************************************************************/+static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)+{+	MV_U32 val,timeout;++	/* set the address */+	val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;+	/* set command */+	val |= command;	+	MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);+	/* WA add a delay */+	mvOsDelay(1);++	/* clear Int flag */+	twsiIntFlgClr(chanNum);++	/* wait for Int to be Set */+	timeout = 0;+	while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));++	/* check for timeout */+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))+		return MV_TIMEOUT;+	+	/* check the status */+	val = twsiStsGet(chanNum);+	if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) || +	   ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))+	{+		/* only in debug, since in boot we try to read the SPD of both DRAM, and we don't+			want error messeges in case DIMM doesn't exist. */+		DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\+						,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));+		return MV_FAIL;+	}+	+	return MV_OK;+}++/*******************************************************************************+* twsiDataWrite - Trnasmit a data block over TWSI bus.+*+* DESCRIPTION:+*       This function writes a given data block to TWSI bus in 8 bit granularity.+*	first The function waits for interrupt flag to be active then+*       For each 8-bit data:+*        The function writes data to data register. It then clears +*        interrupt flag which drives the data on the TWSI bus. +*        The function then waits for interrupt flag to be active and status +*        0x28 to be set. +*      +*+* INPUT:+*	chanNum - TWSI channel+*       pBlock - Data block.+*	blockSize - number of chars in pBlock.+*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK - if transmiting the block completed succesfully,+*	MV_BAD_PARAM - if pBlock is NULL,+*	MV_FAIL otherwmise.+*+*******************************************************************************/+static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)+{+	MV_U32 timeout, temp, blockSizeWr = blockSize;++	if(NULL == pBlock)+		return MV_BAD_PARAM;++	/* wait for Int to be Set */+	timeout = 0;+	while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));++	/* check for timeout */+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))+		return MV_TIMEOUT;++	while(blockSizeWr)+	{+		/* write the data*/+		MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);+		DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\+						blockSize - blockSizeWr, *pBlock));+		pBlock++;+		blockSizeWr--;++		twsiIntFlgClr(chanNum);++		/* wait for Int to be Set */+		timeout = 0;+		while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));++		/* check for timeout */+		if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))+			return MV_TIMEOUT;++		/* check the status */+		temp = twsiStsGet(chanNum);+		if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC) +		{+			mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);+			return MV_FAIL;+		}+		+	}++	return MV_OK;+}++/*******************************************************************************+* twsiDataReceive - Receive data block from TWSI bus.+*+* DESCRIPTION:+*       This function receive data block from TWSI bus in 8bit granularity +*       into pBlock buffer.+*	first The function waits for interrupt flag to be active then+*       For each 8-bit data:+*        It clears the interrupt flag which allows the next data to be +*        received from TWSI bus.+*	 The function waits for interrupt flag to be active,+*	 and status reg is 0x50. +*	 Then the function reads data from data register, and copies it to +*	 the given buffer. +*+* INPUT:+*	chanNum - TWSI channel+*       blockSize - number of bytes to read.+*+* OUTPUT:+*       pBlock - Data block.+*+* RETURN:+*       MV_OK - if receive transaction completed succesfully,+*	MV_BAD_PARAM - if pBlock is NULL,+*	MV_FAIL otherwmise.+*+*******************************************************************************/+static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)+{+	MV_U32 timeout, temp, blockSizeRd = blockSize;+	if(NULL == pBlock)+		return MV_BAD_PARAM;++	/* wait for Int to be Set */+	timeout = 0;+	while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));++	/* check for timeout */+	if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))+		return MV_TIMEOUT;++	while(blockSizeRd)+	{+		if(blockSizeRd == 1)+		{+			/* clear ack and Int flag */+			temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));+			temp &=  ~(TWSI_CONTROL_ACK);+			MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);+		}+		twsiIntFlgClr(chanNum);+		/* wait for Int to be Set */+		timeout = 0;+		while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));++		/* check for timeout */+		if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))+			return MV_TIMEOUT;++		/* check the status */+		temp = twsiStsGet(chanNum);+		if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))+		{+			mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);+			return MV_FAIL;+		}+		else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))+		{+			mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);+			return MV_FAIL;+		}+		+		/* read the data*/+		*pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));+		DB(mvOsPrintf("TWSI: twsiDataReceive  place %d read %x \n",\+						blockSize - blockSizeRd,*pBlock));+		pBlock++;+		blockSizeRd--;+	}++	return MV_OK;+}++++/*******************************************************************************+* twsiTargetOffsSet - Set TWST target offset on TWSI bus.+*+* DESCRIPTION:+*       The function support TWSI targets that have inside address space (for+*       example EEPROMs). The function:+*       1) Convert the given offset into pBlock and size.+*		in case the offset should be set to a TWSI slave which support +*		more then 256 bytes offset, the offset setting will be done+*		in 2 transactions.+*       2) Use twsiDataTransmit to place those on the bus.+*+* INPUT:+*	chanNum - TWSI channel+*       offset - offset to be set on the EEPROM device.+*	moreThen256 - whether the EEPROM device support more then 256 byte offset. +*+* OUTPUT:+*       None.+*+* RETURN:+*       MV_OK - if setting the offset completed succesfully.+*	MV_FAIL otherwmise.+*+*******************************************************************************/+static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)+{+	MV_U8 offBlock[2];+	MV_U32 offSize;++	if(moreThen256 == MV_TRUE)+	{+		offBlock[0] = (offset >> 8) & 0xff;+		offBlock[1] = offset & 0xff;+		offSize = 2;+	}+	else+	{+		offBlock[0] = offset & 0xff;+		offSize = 1;+	}+	DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\+							offSize,offBlock[0],offBlock[1]));+	return twsiDataTransmit(chanNum, offBlock, offSize);++}++/*******************************************************************************+* mvTwsiRead - Read data block from a TWSI Slave.+*+* DESCRIPTION:+*       The function calls the following functions:+*       -) mvTwsiStartBitSet();+*	if(EEPROM device)+*       	-) mvTwsiAddrSet(w);+*       	-) twsiTargetOffsSet();+*       	-) mvTwsiStartBitSet();+*       -) mvTwsiAddrSet(r);+*       -) twsiDataReceive();+*       -) mvTwsiStopBitSet();+*+* INPUT:+*	chanNum - TWSI channel+*      	pTwsiSlave - Twsi Slave structure. +*       blockSize - number of bytes to read.	+*+* OUTPUT:+*      	pBlock - Data block.+*+* RETURN:+*       MV_OK - if EEPROM read transaction completed succesfully,+* 	MV_BAD_PARAM - if pBlock is NULL,+*	MV_FAIL otherwmise.+*+*******************************************************************************/+MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)+{+	if((NULL == pBlock) || (NULL == pTwsiSlave))+		return MV_BAD_PARAM;+	if(MV_OK != mvTwsiStartBitSet(chanNum))+	{+		mvTwsiStopBitSet(chanNum);+		 return MV_FAIL;+	}+	+	DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));+	+	/* in case offset exsist (i.e. eeprom ) */+	if(MV_TRUE == pTwsiSlave->validOffset)+	{+		if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE)) +		{+			mvTwsiStopBitSet(chanNum);+			return MV_FAIL;+		} +		DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));+		if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256)) +		{+			mvTwsiStopBitSet(chanNum);+			return MV_FAIL;+		}+		DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));+		if(MV_OK != mvTwsiStartBitSet(chanNum)) +		{+			mvTwsiStopBitSet(chanNum);+			return MV_FAIL;+		}+		DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));+	}+	if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ)) +	{+		mvTwsiStopBitSet(chanNum);+		return MV_FAIL;+	} +	DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));+	if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))+	{+		mvTwsiStopBitSet(chanNum);+		return MV_FAIL;+	}+	DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));++	if(MV_OK != mvTwsiStopBitSet(chanNum))+	{+		return MV_FAIL;+	}++	twsiAckBitSet(chanNum);++	DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));++	return MV_OK;+}++/*******************************************************************************+* mvTwsiWrite - Write data block to a TWSI Slave.+*+* DESCRIPTION:+*       The function calls the following functions:+*       -) mvTwsiStartBitSet();+*       -) mvTwsiAddrSet();+*	-)if(EEPROM device)+*       	-) twsiTargetOffsSet();+*       -) twsiDataTransmit();+*       -) mvTwsiStopBitSet();+*+* INPUT:+*	chanNum - TWSI channel+*      	eepromAddress - eeprom address. +*       blockSize - number of bytes to write.	+*      	pBlock - Data block.+*+* OUTPUT:+*	None+*+* RETURN:+*       MV_OK - if EEPROM read transaction completed succesfully.+*	MV_BAD_PARAM - if pBlock is NULL,+*	MV_FAIL otherwmise.+*+* NOTE: Part of the EEPROM, required that the offset will be aligned to the+*	max write burst supported.+*******************************************************************************/+MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)+{+	if((NULL == pBlock) || (NULL == pTwsiSlave))+		return MV_BAD_PARAM;++	if(MV_OK != mvTwsiStartBitSet(chanNum)) +	{+		mvTwsiStopBitSet(chanNum);+		return MV_FAIL;+	}++	DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));+	if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))+	{+		mvTwsiStopBitSet(chanNum);+		return MV_FAIL;+	}+	DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));++	/* in case offset exsist (i.e. eeprom ) */+	if(MV_TRUE == pTwsiSlave->validOffset)+	{+		if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256)) +		{+			mvTwsiStopBitSet(chanNum);+			return MV_FAIL;+		}+		DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));+	}+	if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize)) +	{+		mvTwsiStopBitSet(chanNum);+		return MV_FAIL;+	}+	DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));+	if(MV_OK != mvTwsiStopBitSet(chanNum)) +	{+		return MV_FAIL;+	}+	DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));++	return MV_OK;+}diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h	2010-11-09 20:28:12.231824496 +0100@@ -0,0 +1,121 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+#ifndef __INCmvTwsiH+#define __INCmvTwsiH++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* need to update this includes */+#include "twsi/mvTwsiSpec.h"+#include "ctrlEnv/mvCtrlEnvLib.h"+++/* The TWSI interface supports both 7-bit and 10-bit addressing.            */+/* This enumerator describes addressing type.                               */+typedef enum _mvTwsiAddrType+{+    ADDR7_BIT,                      /* 7 bit address    */+    ADDR10_BIT                      /* 10 bit address   */+}MV_TWSI_ADDR_TYPE;++/* This structure describes TWSI address.                                   */+typedef struct _mvTwsiAddr+{+    MV_U32              address;    /* address          */+    MV_TWSI_ADDR_TYPE   type;       /* Address type     */+}MV_TWSI_ADDR;++/* This structure describes a TWSI slave.                                   */+typedef struct _mvTwsiSlave+{+    MV_TWSI_ADDR	slaveAddr;+    MV_BOOL 		validOffset;		/* whether the slave has offset (i.e. Eeprom  etc.) 	*/+    MV_U32		offset;		/* offset in the slave.					*/+    MV_BOOL 		moreThen256;	/* whether the ofset is bigger then 256 		*/+}MV_TWSI_SLAVE;++/* This enumerator describes TWSI protocol commands.                        */+typedef enum _mvTwsiCmd+{+    MV_TWSI_WRITE,   /* TWSI write command - 0 according to spec   */+    MV_TWSI_READ   /* TWSI read command  - 1 according to spec */+}MV_TWSI_CMD;++MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);+MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);+MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);++MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable); +MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);+MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);+++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvTwsiH */+diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h	2010-11-09 20:28:12.272374071 +0100@@ -0,0 +1,160 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++This software file (the "File") is owned and distributed by Marvell +International Ltd. and/or its affiliates ("Marvell") under the following+alternative licensing terms.  Once you have made an election to distribute the+File under one of the following license alternatives, please (i) delete this+introductory statement regarding license alternatives, (ii) delete the two+license alternatives that you have not elected to use and (iii) preserve the+Marvell copyright notice above.++********************************************************************************+Marvell Commercial License Option++If you received this File from Marvell and you have entered into a commercial+license agreement (a "Commercial License") with Marvell, the File is licensed+to you under the terms of the applicable Commercial License.++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.+********************************************************************************+Marvell BSD License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:++    *   Redistributions of source code must retain the above copyright notice,+	    this list of conditions and the following disclaimer. ++    *   Redistributions in binary form must reproduce the above copyright+        notice, this list of conditions and the following disclaimer in the+        documentation and/or other materials provided with the distribution. ++    *   Neither the name of Marvell nor the names of its contributors may be +        used to endorse or promote products derived from this software without +        specific prior written permission. +    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++*******************************************************************************/+/****************************************/+/* TWSI Registers                        */+/****************************************/+#ifndef __INCmvTwsiSpech+#define __INCmvTwsiSpech++#ifdef __cplusplus+extern "C" {+#endif /* __cplusplus */++/* defines */+#define TWSI_SLAVE_ADDR_REG(chanNum)	(TWSI_SLAVE_BASE(chanNum)+ 0x00)++#define TWSI_SLAVE_ADDR_GCE_ENA		BIT0+#define TWSI_SLAVE_ADDR_7BIT_OFFS	0x1+#define TWSI_SLAVE_ADDR_7BIT_MASK 	(0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)+#define TWSI_SLAVE_ADDR_10BIT_OFFS	0x7+#define TWSI_SLAVE_ADDR_10BIT_MASK 	0x300+#define	TWSI_SLAVE_ADDR_10BIT_CONST 	0xF0+++#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum)	(TWSI_SLAVE_BASE(chanNum) + 0x10)+#define TWSI_EXTENDED_SLAVE_OFFS 	0+#define TWSI_EXTENDED_SLAVE_MASK	(0xFF << TWSI_EXTENDED_SLAVE_OFFS)+++#define TWSI_DATA_REG(chanNum)		(TWSI_SLAVE_BASE(chanNum) + 0x04)+#define TWSI_DATA_COMMAND_OFFS		0x0+#define TWSI_DATA_COMMAND_MASK 		(0x1 << TWSI_DATA_COMMAND_OFFS)+#define TWSI_DATA_COMMAND_WR		(0x1 << TWSI_DATA_COMMAND_OFFS)+#define TWSI_DATA_COMMAND_RD		(0x0 << TWSI_DATA_COMMAND_OFFS)+#define TWSI_DATA_ADDR_7BIT_OFFS	0x1+#define TWSI_DATA_ADDR_7BIT_MASK 	(0xFF << TWSI_DATA_ADDR_7BIT_OFFS)+#define TWSI_DATA_ADDR_10BIT_OFFS	0x7+#define TWSI_DATA_ADDR_10BIT_MASK	0x300+#define TWSI_DATA_ADDR_10BIT_CONST	0xF0+++#define TWSI_CONTROL_REG(chanNum)	(TWSI_SLAVE_BASE(chanNum) + 0x08)+#define TWSI_CONTROL_ACK            	BIT2+#define TWSI_CONTROL_INT_FLAG_SET   	BIT3+#define TWSI_CONTROL_STOP_BIT    	BIT4+#define TWSI_CONTROL_START_BIT 		BIT5 +#define TWSI_CONTROL_ENA     		BIT6+#define TWSI_CONTROL_INT_ENA    	BIT7+++#define TWSI_STATUS_BAUDE_RATE_REG(chanNum)	(TWSI_SLAVE_BASE(chanNum) + 0x0c)+#define TWSI_BAUD_RATE_N_OFFS		0+#define TWSI_BAUD_RATE_N_MASK		(0x7 << TWSI_BAUD_RATE_N_OFFS)+#define TWSI_BAUD_RATE_M_OFFS   	3+#define TWSI_BAUD_RATE_M_MASK  		(0xF << TWSI_BAUD_RATE_M_OFFS)++#define TWSI_SOFT_RESET_REG(chanNum)	(TWSI_SLAVE_BASE(chanNum) + 0x1c)++/* defines */+#define TWSI_TIMEOUT_VALUE 		0x500 ++/* TWSI status codes */+#define TWSI_BUS_ERROR                                            0x00+#define TWSI_START_CON_TRA                                        0x08+#define TWSI_REPEATED_START_CON_TRA                               0x10+#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC                            0x18+#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC                        0x20+#define TWSI_M_TRAN_DATA_BYTE_ACK_REC                             0x28+#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC                         0x30+#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA                        0x38+#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC                            0x40+#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC                        0x48+#define TWSI_M_REC_RD_DATA_ACK_TRA                                0x50+#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA                            0x58+#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA                        0x60+#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W    0x68+#define TWSI_GNL_CALL_REC_ACK_TRA                                 0x70+#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA        0x78+#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN               0x80+#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN           0x88+#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN             0x90+#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN         0x98+#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON                    0xA0+#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA                        0xA8+#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R    0xB0+#define TWSI_SLA_TRA_RD_DATA_ACK_REC                              0xB8+#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC                          0xC0+#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC                         0xC8+#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC                        0xD0+#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC                    0xD8+#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC                        0xE0+#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC                    0xE8+#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0                        0xF8+++#ifdef __cplusplus+}+#endif /* __cplusplus */++#endif /* __INCmvTwsiSpech */diff -Nur linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h linux-2.6.36/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h--- linux-2.6.36.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h	2010-11-09 20:28:12.322486315 +0100@@ -0,0 +1,375 @@+/*******************************************************************************+Copyright (C) Marvell International Ltd. and its affiliates++********************************************************************************+Marvell GPL License Option++If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File in accordance with the terms and conditions of the General +Public License Version 2, June 1991 (the "GPL License"), a copy of which is +available along with the File in the license.txt file or by writing to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or +on the worldwide web at http://www.gnu.org/licenses/gpl.txt. ++THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY +DISCLAIMED.  The GPL License provides additional details about this warranty +disclaimer.++*******************************************************************************/+/*******************************************************************************+* mvSysHwCfg.h - Marvell system HW configuration file+*+* DESCRIPTION:+*       None.+*+* DEPENDENCIES:+*       None.+*+*******************************************************************************/++#ifndef __INCmvSysHwConfigh+#define __INCmvSysHwConfigh++#include "../../../../include/linux/autoconf.h"++#define CONFIG_MARVELL	1++/* includes */+#define _1K         0x00000400+#define _4K         0x00001000+#define _8K         0x00002000+#define _16K        0x00004000+#define _32K        0x00008000+#define _64K        0x00010000+#define _128K       0x00020000+#define _256K       0x00040000+#define _512K       0x00080000++#define _1M         0x00100000+#define _2M         0x00200000+#define _4M         0x00400000+#define _8M         0x00800000+#define _16M        0x01000000+#define _32M        0x02000000+#define _64M        0x04000000+#define _128M       0x08000000+#define _256M       0x10000000+#define _512M       0x20000000++#define _1G         0x40000000+#define _2G         0x80000000++/****************************************/+/* Soc supporeted Units definitions	*/+/****************************************/++#ifdef CONFIG_MV_INCLUDE_PEX+#define MV_INCLUDE_PEX+#endif+#ifdef CONFIG_MV_INCLUDE_TWSI+#define MV_INCLUDE_TWSI+#endif+#ifdef CONFIG_MV_INCLUDE_CESA+#define MV_INCLUDE_CESA+#endif+#ifdef CONFIG_MV_INCLUDE_GIG_ETH+#define MV_INCLUDE_GIG_ETH+#endif+#ifdef CONFIG_MV_INCLUDE_INTEG_SATA+#define MV_INCLUDE_INTEG_SATA+#define MV_INCLUDE_SATA+#endif+#ifdef CONFIG_MV_INCLUDE_USB+#define MV_INCLUDE_USB+#define MV_USB_VOLTAGE_FIX+#endif+#ifdef CONFIG_MV_INCLUDE_NAND+#define MV_INCLUDE_NAND+#endif+#ifdef CONFIG_MV_INCLUDE_TDM+#define MV_INCLUDE_TDM+#endif+#ifdef CONFIG_MV_INCLUDE_XOR+#define MV_INCLUDE_XOR+#endif+#ifdef CONFIG_MV_INCLUDE_TWSI+#define MV_INCLUDE_TWSI+#endif+#ifdef CONFIG_MV_INCLUDE_UART+#define MV_INCLUDE_UART+#endif+#ifdef CONFIG_MV_INCLUDE_SPI+#define MV_INCLUDE_SPI+#endif+#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD+#define MV_INCLUDE_SFLASH_MTD+#endif+#ifdef CONFIG_MV_INCLUDE_AUDIO+#define MV_INCLUDE_AUDIO+#endif+#ifdef CONFIG_MV_INCLUDE_TS+#define MV_INCLUDE_TS+#endif+#ifdef CONFIG_MV_INCLUDE_SDIO+#define MV_INCLUDE_SDIO+#endif+++/* NAND flash stuff */+#ifdef CONFIG_MV_NAND_BOOT+#define MV_NAND_BOOT+#endif+#ifdef CONFIG_MV_NAND+#define MV_NAND+#endif++/* SPI flash stuff */+#ifdef CONFIG_MV_SPI_BOOT+#define MV_SPI_BOOT+#endif+++/****************************************************************/+/************* General    configuration ********************/+/****************************************************************/++/* Enable Clock Power Control */+#define MV_INCLUDE_CLK_PWR_CNTRL++/* Disable the DEVICE BAR in the PEX */+#define MV_DISABLE_PEX_DEVICE_BAR++/* Allow the usage of early printings during initialization */+#define MV_INCLUDE_EARLY_PRINTK++/****************************************************************/+/************* NFP configuration ********************************/+/****************************************************************/+#define MV_NFP_SEC_Q_SIZE		64+#define MV_NFP_SEC_REQ_Q_SIZE		1000++++/****************************************************************/+/************* CESA configuration ********************/+/****************************************************************/++#ifdef MV_INCLUDE_CESA++#define MV_CESA_MAX_CHAN               4++/* Use 2K of SRAM */+#define MV_CESA_MAX_BUF_SIZE           1600++#endif /* MV_INCLUDE_CESA */++#if defined(CONFIG_MV_INCLUDE_GIG_ETH)++#ifdef CONFIG_MV_NFP_STATS+#define MV_FP_STATISTICS+#else+#undef MV_FP_STATISTICS+#endif+/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */+#define MV_ETH_SKB_REUSE_DEFAULT    1+/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */+#define MV_ETH_TX_EN_DEFAULT        0++/* un-comment if you want to perform tx_done from within the poll function */+/* #define ETH_TX_DONE_ISR */++/* put descriptors in uncached memory */+/* #define ETH_DESCR_UNCACHED */++/* Descriptors location: DRAM/internal-SRAM */+#define ETH_DESCR_IN_SDRAM+#undef  ETH_DESCR_IN_SRAM    /* No integrated SRAM in 88Fxx81 devices */++#if defined(ETH_DESCR_IN_SRAM)+#if defined(ETH_DESCR_UNCACHED)+ #define ETH_DESCR_CONFIG_STR    "Uncached descriptors in integrated SRAM"+#else+ #define ETH_DESCR_CONFIG_STR    "Cached descriptors in integrated SRAM"+#endif+#elif defined(ETH_DESCR_IN_SDRAM)+#if defined(ETH_DESCR_UNCACHED)+ #define ETH_DESCR_CONFIG_STR    "Uncached descriptors in DRAM"+#else+ #define ETH_DESCR_CONFIG_STR    "Cached descriptors in DRAM"+#endif+#else + #error "Ethernet descriptors location undefined"+#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/++/* SW Sync-Barrier: not relevant for 88fxx81*/+/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */+/* In RX the CPU theoretically might see himself as the descriptor owner,      */+/* although the buffer hadn't been written to DRAM yet. Performance cost.      */+/* #define INCLUDE_SYNC_BARR */++/* Buffers cache coherency method (buffers in DRAM) */+#ifndef MV_CACHE_COHER_SW+/* Taken from mvCommon.h */+/* Memory uncached, HW or SW cache coherency is not needed */+#define MV_UNCACHED             0   +/* Memory cached, HW cache coherency supported in WriteThrough mode */+#define MV_CACHE_COHER_HW_WT    1+/* Memory cached, HW cache coherency supported in WriteBack mode */+#define MV_CACHE_COHER_HW_WB    2+/* Memory cached, No HW cache coherency, Cache coherency must be in SW */+#define MV_CACHE_COHER_SW       3++#endif++/* DRAM cache coherency configuration */+#define MV_CACHE_COHERENCY  MV_CACHE_COHER_SW+++#define ETHER_DRAM_COHER    MV_CACHE_COHER_SW   /* No HW coherency in 88Fxx81 devices */++#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)+ #define ETH_SDRAM_CONFIG_STR    "DRAM HW cache coherency (write-back)"+#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)+ #define ETH_SDRAM_CONFIG_STR    "DRAM HW cache coherency (write-through)"+#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)+ #define ETH_SDRAM_CONFIG_STR    "DRAM SW cache-coherency"+#elif (ETHER_DRAM_COHER == MV_UNCACHED)+#   define ETH_SDRAM_CONFIG_STR  "DRAM uncached"+#else+ #error "Ethernet-DRAM undefined"+#endif /* ETHER_DRAM_COHER */+++/****************************************************************/+/************* Ethernet driver configuration ********************/+/****************************************************************/++/* port's default queueus */+#define ETH_DEF_TXQ         0+#define ETH_DEF_RXQ         0 ++#define MV_ETH_RX_Q_NUM     CONFIG_MV_ETH_RX_Q_NUM+#define MV_ETH_TX_Q_NUM     CONFIG_MV_ETH_TX_Q_NUM++/* interrupt coalescing setting */+#define ETH_TX_COAL    		    200+#define ETH_RX_COAL    		    200++/* Checksum offloading */+#define TX_CSUM_OFFLOAD+#define RX_CSUM_OFFLOAD++#endif /* CONFIG_MV_INCLUDE_GIG_ETH */++/****************************************************************/+/*************** Telephony configuration ************************/+/****************************************************************/+#if defined(CONFIG_MV_TDM_LINEAR_MODE)+ #define MV_TDM_LINEAR_MODE+#elif defined(CONFIG_MV_TDM_ULAW_MODE)+ #define MV_TDM_ULAW_MODE+#endif++#if defined(CONFIG_MV_TDM_5CHANNELS)+ #define MV_TDM_5CHANNELS +#endif++#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)+ #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE+#endif++/* We use the following registers to store DRAM interface pre configuration   */+/* auto-detection results													  */+/* IMPORTANT: We are using mask register for that purpose. Before writing     */+/* to units mask register, make sure main maks register is set to disable     */+/* all interrupts.                                                            */+#define DRAM_BUF_REG0   0x30810 /* sdram bank 0 size            */  +#define DRAM_BUF_REG1   0x30820 /* sdram config                 */+#define DRAM_BUF_REG2   0x30830 /* sdram mode                   */+#define DRAM_BUF_REG3   0x308c4 /* dunit control low            */          +#define DRAM_BUF_REG4   0x60a90 /* sdram address control        */+#define DRAM_BUF_REG5   0x60a94 /* sdram timing control low     */+#define DRAM_BUF_REG6   0x60a98 /* sdram timing control high    */+#define DRAM_BUF_REG7   0x60a9c /* sdram ODT control low        */+#define DRAM_BUF_REG8   0x60b90 /* sdram ODT control high       */+#define DRAM_BUF_REG9   0x60b94 /* sdram Dunit ODT control      */+#define DRAM_BUF_REG10  0x60b98 /* sdram Extended Mode          */+#define DRAM_BUF_REG11  0x60b9c /* sdram Ddr2 Time Low Reg      */+#define DRAM_BUF_REG12  0x60a00 /* sdram Ddr2 Time High Reg     */+#define DRAM_BUF_REG13  0x60a04 /* dunit Ctrl High              */+#define DRAM_BUF_REG14  0x60b00 /* sdram second DIMM exist      */++/* Following the pre-configuration registers default values restored after    */+/* auto-detection is done                                                     */+#define DRAM_BUF_REG_DV 0++/* System Mapping */+#define SDRAM_CS0_BASE  0x00000000+#define SDRAM_CS0_SIZE  _256M++#define SDRAM_CS1_BASE  0x10000000+#define SDRAM_CS1_SIZE  _256M++#define SDRAM_CS2_BASE  0x20000000+#define SDRAM_CS2_SIZE  _256M++#define SDRAM_CS3_BASE  0x30000000+#define SDRAM_CS3_SIZE  _256M++/* PEX */+#define PEX0_MEM_BASE 0xe8000000+#define PEX0_MEM_SIZE _128M++#define PEX0_IO_BASE 0xf2000000+#define PEX0_IO_SIZE _1M++/* Device Chip Selects */+#define NFLASH_CS_BASE 0xfa000000+#define NFLASH_CS_SIZE _2M++#define SPI_CS_BASE 0xf4000000+#define SPI_CS_SIZE _16M++#define CRYPT_ENG_BASE	0xf0000000+#define CRYPT_ENG_SIZE	_2M++#define BOOTDEV_CS_BASE	0xff800000+#define BOOTDEV_CS_SIZE _8M++/* CS2 - BOOTROM */+#define DEVICE_CS2_BASE 0xff900000+#define DEVICE_CS2_SIZE _1M++/* PEX Work arround */+/* the target we will use for the workarround */+#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM+/*a flag that indicates if we are going to use the +size and base of the target we using for the workarround+window */+#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1+/* if the above flag is 0 then the following values+will be used for the workarround window base and size,+otherwise the following defines will be ignored */+#define PEX_CONFIG_RW_WA_BASE 0xF3000000+#define PEX_CONFIG_RW_WA_SIZE _16M++/* Internal registers: size is defined in Controllerenvironment */+#define INTER_REGS_BASE	0xFEE00000++/* DRAM detection stuff */+#define MV_DRAM_AUTO_SIZE++/* Board clock detection */+#define TCLK_AUTO_DETECT    	/* Use Tclk auto detection   */+#define SYSCLK_AUTO_DETECT	/* Use SysClk auto detection */+#define PCLCK_AUTO_DETECT  	/* Use PClk auto detection   */+#define L2CLK_AUTO_DETECT 	/* Use L2Clk auto detection   */++/* PEX-PCI\PCI-PCI Bridge*/+#define PCI0_IF_PTP		0		/* Bridge exist on pciIf0*/++ ++#endif /* __INCmvSysHwConfigh */+diff -Nur linux-2.6.36.orig/crypto/ocf/Makefile linux-2.6.36/crypto/ocf/Makefile--- linux-2.6.36.orig/crypto/ocf/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/Makefile	2010-11-09 20:28:12.342495369 +0100@@ -0,0 +1,124 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++OCF_OBJS = crypto.o criov.o++ifdef CONFIG_OCF_RANDOMHARVEST+	OCF_OBJS += random.o+endif++ifdef CONFIG_OCF_FIPS+	OCF_OBJS += rndtest.o+endif++# Add in autoconf.h to get #defines for CONFIG_xxx+AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h+ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))+	EXTRA_CFLAGS += -include $(AUTOCONF_H)+	export EXTRA_CFLAGS+endif++ifndef obj+	obj ?= .+	_obj = subdir+	mod-subdirs := safe hifn ixp4xx talitos ocfnull+	export-objs += crypto.o criov.o random.o+	list-multi += ocf.o+	_slash :=+else+	_obj = obj+	_slash := /+endif++EXTRA_CFLAGS += -I$(obj)/.++obj-$(CONFIG_OCF_OCF)         += ocf.o+obj-$(CONFIG_OCF_CRYPTODEV)   += cryptodev.o+obj-$(CONFIG_OCF_CRYPTOSOFT)  += cryptosoft.o+obj-$(CONFIG_OCF_BENCH)       += ocf-bench.o++$(_obj)-$(CONFIG_OCF_SAFE)    += safe$(_slash)+$(_obj)-$(CONFIG_OCF_HIFN)    += hifn$(_slash)+$(_obj)-$(CONFIG_OCF_IXP4XX)  += ixp4xx$(_slash)+$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)+$(_obj)-$(CONFIG_OCF_PASEMI)  += pasemi$(_slash)+$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)+$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)+$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)+$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)+$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)++ocf-objs := $(OCF_OBJS)++$(list-multi) dummy1: $(ocf-objs)+	$(LD) -r -o $@ $(ocf-objs)++.PHONY:+clean:+	rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c+	rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif++#+# release gen targets+#++.PHONY: patch+patch:+	REL=`date +%Y%m%d`; \+		patch=ocf-linux-$$REL.patch; \+		patch24=ocf-linux-24-$$REL.patch; \+		patch26=ocf-linux-26-$$REL.patch; \+		( \+			find . -name Makefile; \+			find . -name Config.in; \+			find . -name Kconfig; \+			find . -name README; \+			find . -name '*.[ch]' | grep -v '.mod.c'; \+		) | while read t; do \+			diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \+		done > $$patch; \+		cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \+		cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26++.PHONY: tarball+tarball:+	REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \+		CURDIR=`pwd`; \+		rm -rf /tmp/ocf-linux-$$REL*; \+		mkdir -p $$RELDIR/tools; \+		cp README* $$RELDIR; \+		cp patches/openss*.patch $$RELDIR; \+		cp patches/crypto-tools.patch $$RELDIR; \+		cp tools/[!C]* $$RELDIR/tools; \+		cd ..; \+		tar cvf $$RELDIR/ocf-linux.tar \+					--exclude=CVS \+					--exclude=.* \+					--exclude=*.o \+					--exclude=*.ko \+					--exclude=*.mod.* \+					--exclude=README* \+					--exclude=ocf-*.patch \+					--exclude=ocf/patches/openss*.patch \+					--exclude=ocf/patches/crypto-tools.patch \+					--exclude=ocf/tools \+					ocf; \+		gzip -9 $$RELDIR/ocf-linux.tar; \+		cd /tmp; \+		tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \+		gzip -9 ocf-linux-$$REL.tar; \+		cd $$CURDIR/../../user; \+		rm -rf /tmp/crypto-tools-$$REL*; \+		tar cvf /tmp/crypto-tools-$$REL.tar \+					--exclude=CVS \+					--exclude=.* \+					--exclude=*.o \+					--exclude=cryptotest \+					--exclude=cryptokeytest \+					crypto-tools; \+		gzip -9 /tmp/crypto-tools-$$REL.tar+diff -Nur linux-2.6.36.orig/crypto/ocf/ocf-bench.c linux-2.6.36/crypto/ocf/ocf-bench.c--- linux-2.6.36.orig/crypto/ocf/ocf-bench.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ocf-bench.c	2010-11-09 20:28:12.381251524 +0100@@ -0,0 +1,436 @@+/*+ * A loadable module that benchmarks the OCF crypto speed from kernel space.+ *+ * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this product+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ */+++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/wait.h>+#include <linux/sched.h>+#include <linux/spinlock.h>+#include <linux/version.h>+#include <linux/interrupt.h>+#include <cryptodev.h>++#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK+#define BENCH_IXP_ACCESS_LIB 1+#endif+#ifdef BENCH_IXP_ACCESS_LIB+#include <IxTypes.h>+#include <IxOsBuffMgt.h>+#include <IxNpeDl.h>+#include <IxCryptoAcc.h>+#include <IxQMgr.h>+#include <IxOsServices.h>+#include <IxOsCacheMMU.h>+#endif++/*+ * support for access lib version 1.4+ */+#ifndef IX_MBUF_PRIV+#define IX_MBUF_PRIV(x) ((x)->priv)+#endif++/*+ * the number of simultaneously active requests+ */+static int request_q_len = 20;+module_param(request_q_len, int, 0);+MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");+/*+ * how many requests we want to have processed+ */+static int request_num = 1024;+module_param(request_num, int, 0);+MODULE_PARM_DESC(request_num, "run for at least this many requests");+/*+ * the size of each request+ */+static int request_size = 1500;+module_param(request_size, int, 0);+MODULE_PARM_DESC(request_size, "size of each request");++/*+ * a structure for each request+ */+typedef struct  {+	struct work_struct work;+#ifdef BENCH_IXP_ACCESS_LIB+	IX_MBUF mbuf;+#endif+	unsigned char *buffer;+} request_t;++static request_t *requests;++static int outstanding;+static int total;++/*************************************************************************/+/*+ * OCF benchmark routines+ */++static uint64_t ocf_cryptoid;+static int ocf_init(void);+static int ocf_cb(struct cryptop *crp);+static void ocf_request(void *arg);+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void ocf_request_wq(struct work_struct *work);+#endif++static int+ocf_init(void)+{+	int error;+	struct cryptoini crie, cria;+	struct cryptodesc crda, crde;++	memset(&crie, 0, sizeof(crie));+	memset(&cria, 0, sizeof(cria));+	memset(&crde, 0, sizeof(crde));+	memset(&crda, 0, sizeof(crda));++	cria.cri_alg  = CRYPTO_SHA1_HMAC;+	cria.cri_klen = 20 * 8;+	cria.cri_key  = "0123456789abcdefghij";++	crie.cri_alg  = CRYPTO_3DES_CBC;+	crie.cri_klen = 24 * 8;+	crie.cri_key  = "0123456789abcdefghijklmn";++	crie.cri_next = &cria;++	error = crypto_newsession(&ocf_cryptoid, &crie, 0);+	if (error) {+		printk("crypto_newsession failed %d\n", error);+		return -1;+	}+	return 0;+}++static int+ocf_cb(struct cryptop *crp)+{+	request_t *r = (request_t *) crp->crp_opaque;++	if (crp->crp_etype)+		printk("Error in OCF processing: %d\n", crp->crp_etype);+	total++;+	crypto_freereq(crp);+	crp = NULL;++	if (total > request_num) {+		outstanding--;+		return 0;+	}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+	INIT_WORK(&r->work, ocf_request_wq);+#else+	INIT_WORK(&r->work, ocf_request, r);+#endif+	schedule_work(&r->work);+	return 0;+}+++static void+ocf_request(void *arg)+{+	request_t *r = arg;+	struct cryptop *crp = crypto_getreq(2);+	struct cryptodesc *crde, *crda;++	if (!crp) {+		outstanding--;+		return;+	}++	crde = crp->crp_desc;+	crda = crde->crd_next;++	crda->crd_skip = 0;+	crda->crd_flags = 0;+	crda->crd_len = request_size;+	crda->crd_inject = request_size;+	crda->crd_alg = CRYPTO_SHA1_HMAC;+	crda->crd_key = "0123456789abcdefghij";+	crda->crd_klen = 20 * 8;++	crde->crd_skip = 0;+	crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;+	crde->crd_len = request_size;+	crde->crd_inject = request_size;+	crde->crd_alg = CRYPTO_3DES_CBC;+	crde->crd_key = "0123456789abcdefghijklmn";+	crde->crd_klen = 24 * 8;++	crp->crp_ilen = request_size + 64;+	crp->crp_flags = CRYPTO_F_CBIMM;+	crp->crp_buf = (caddr_t) r->buffer;+	crp->crp_callback = ocf_cb;+	crp->crp_sid = ocf_cryptoid;+	crp->crp_opaque = (caddr_t) r;+	crypto_dispatch(crp);+}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void+ocf_request_wq(struct work_struct *work)+{+	request_t *r = container_of(work, request_t, work);+	ocf_request(r);+}+#endif++/*************************************************************************/+#ifdef BENCH_IXP_ACCESS_LIB+/*************************************************************************/+/*+ * CryptoAcc benchmark routines+ */++static IxCryptoAccCtx ixp_ctx;+static UINT32 ixp_ctx_id;+static IX_MBUF ixp_pri;+static IX_MBUF ixp_sec;+static int ixp_registered = 0;++static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,+					IxCryptoAccStatus status);+static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,+					IxCryptoAccStatus status);+static void ixp_request(void *arg);+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void ixp_request_wq(struct work_struct *work);+#endif++static int+ixp_init(void)+{+	IxCryptoAccStatus status;++	ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;+	ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;+	ixp_ctx.cipherCtx.cipherKeyLen = 24;+	ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;+	ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;+	memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);++	ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;+	ixp_ctx.authCtx.authDigestLen = 12;+	ixp_ctx.authCtx.aadLen = 0;+	ixp_ctx.authCtx.authKeyLen = 20;+	memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);++	ixp_ctx.useDifferentSrcAndDestMbufs = 0;+	ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;++	IX_MBUF_MLEN(&ixp_pri)  = IX_MBUF_PKT_LEN(&ixp_pri) = 128;+	IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);+	IX_MBUF_MLEN(&ixp_sec)  = IX_MBUF_PKT_LEN(&ixp_sec) = 128;+	IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);++	status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,+			ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);++	if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {+		while (!ixp_registered)+			schedule();+		return ixp_registered < 0 ? -1 : 0;+	}++	printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);+	return -1;+}++static void+ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)+{+	if (bufp) {+		IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;+		kfree(IX_MBUF_MDATA(bufp));+		IX_MBUF_MDATA(bufp) = NULL;+	}++	if (IX_CRYPTO_ACC_STATUS_WAIT == status)+		return;+	if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)+		ixp_registered = 1;+	else+		ixp_registered = -1;+}++static void+ixp_perform_cb(+	UINT32 ctx_id,+	IX_MBUF *sbufp,+	IX_MBUF *dbufp,+	IxCryptoAccStatus status)+{+	request_t *r = NULL;++	total++;+	if (total > request_num) {+		outstanding--;+		return;+	}++	if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {+		printk("crappo %p %p\n", sbufp, r);+		outstanding--;+		return;+	}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+	INIT_WORK(&r->work, ixp_request_wq);+#else+	INIT_WORK(&r->work, ixp_request, r);+#endif+	schedule_work(&r->work);+}++static void+ixp_request(void *arg)+{+	request_t *r = arg;+	IxCryptoAccStatus status;++	memset(&r->mbuf, 0, sizeof(r->mbuf));+	IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;+	IX_MBUF_MDATA(&r->mbuf) = r->buffer;+	IX_MBUF_PRIV(&r->mbuf) = r;+	status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,+			0, request_size, 0, request_size, request_size, r->buffer);+	if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {+		printk("status1 = %d\n", status);+		outstanding--;+		return;+	}+	return;+}++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)+static void+ixp_request_wq(struct work_struct *work)+{+	request_t *r = container_of(work, request_t, work);+	ixp_request(r);+}+#endif++/*************************************************************************/+#endif /* BENCH_IXP_ACCESS_LIB */+/*************************************************************************/++int+ocfbench_init(void)+{+	int i, jstart, jstop;++	printk("Crypto Speed tests\n");++	requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);+	if (!requests) {+		printk("malloc failed\n");+		return -EINVAL;+	}++	for (i = 0; i < request_q_len; i++) {+		/* +64 for return data */+		requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);+		if (!requests[i].buffer) {+			printk("malloc failed\n");+			return -EINVAL;+		}+		memset(requests[i].buffer, '0' + i, request_size + 128);+	}++	/*+	 * OCF benchmark+	 */+	printk("OCF: testing ...\n");+	ocf_init();+	total = outstanding = 0;+	jstart = jiffies;+	for (i = 0; i < request_q_len; i++) {+		outstanding++;+		ocf_request(&requests[i]);+	}+	while (outstanding > 0)+		schedule();+	jstop = jiffies;++	printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,+			jstop - jstart);++#ifdef BENCH_IXP_ACCESS_LIB+	/*+	 * IXP benchmark+	 */+	printk("IXP: testing ...\n");+	ixp_init();+	total = outstanding = 0;+	jstart = jiffies;+	for (i = 0; i < request_q_len; i++) {+		outstanding++;+		ixp_request(&requests[i]);+	}+	while (outstanding > 0)+		schedule();+	jstop = jiffies;++	printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,+			jstop - jstart);+#endif /* BENCH_IXP_ACCESS_LIB */++	for (i = 0; i < request_q_len; i++)+		kfree(requests[i].buffer);+	kfree(requests);+	return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */+}++static void __exit ocfbench_exit(void)+{+}++module_init(ocfbench_init);+module_exit(ocfbench_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");diff -Nur linux-2.6.36.orig/crypto/ocf/ocf-compat.h linux-2.6.36/crypto/ocf/ocf-compat.h--- linux-2.6.36.orig/crypto/ocf/ocf-compat.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ocf-compat.h	2010-11-09 20:28:12.422358492 +0100@@ -0,0 +1,294 @@+#ifndef _BSD_COMPAT_H_+#define _BSD_COMPAT_H_ 1+/****************************************************************************/+/*+ * Provide compat routines for older linux kernels and BSD kernels+ *+ * Written by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this file+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ */+/****************************************************************************/+#ifdef __KERNEL__+/*+ * fake some BSD driver interface stuff specifically for OCF use+ */++typedef struct ocf_device *device_t;++typedef struct {+	int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);+	int (*cryptodev_freesession)(device_t dev, u_int64_t tid);+	int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);+	int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);+} device_method_t;+#define DEVMETHOD(id, func)	id: func++struct ocf_device {+	char name[32];		/* the driver name */+	char nameunit[32];	/* the driver name + HW instance */+	int  unit;+	device_method_t	methods;+	void *softc;+};++#define CRYPTODEV_NEWSESSION(dev, sid, cri) \+	((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))+#define CRYPTODEV_FREESESSION(dev, sid) \+	((*(dev)->methods.cryptodev_freesession)(dev, sid))+#define CRYPTODEV_PROCESS(dev, crp, hint) \+	((*(dev)->methods.cryptodev_process)(dev, crp, hint))+#define CRYPTODEV_KPROCESS(dev, krp, hint) \+	((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))++#define device_get_name(dev)	((dev)->name)+#define device_get_nameunit(dev)	((dev)->nameunit)+#define device_get_unit(dev)	((dev)->unit)+#define device_get_softc(dev)	((dev)->softc)++#define	softc_device_decl \+		struct ocf_device _device; \+		device_t++#define	softc_device_init(_sc, _name, _unit, _methods) \+	if (1) {\+	strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \+	snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \+	(_sc)->_device.unit = _unit; \+	(_sc)->_device.methods = _methods; \+	(_sc)->_device.softc = (void *) _sc; \+	*(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \+	} else++#define	softc_get_device(_sc)	(&(_sc)->_device)++/*+ * iomem support for 2.4 and 2.6 kernels+ */+#include <linux/version.h>+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+#define ocf_iomem_t	unsigned long++/*+ * implement simple workqueue like support for older kernels+ */++#include <linux/tqueue.h>++#define work_struct tq_struct++#define INIT_WORK(wp, fp, ap) \+	do { \+		(wp)->sync = 0; \+		(wp)->routine = (fp); \+		(wp)->data = (ap); \+	} while (0)++#define schedule_work(wp) \+	do { \+		queue_task((wp), &tq_immediate); \+		mark_bh(IMMEDIATE_BH); \+	} while (0)++#define flush_scheduled_work()	run_task_queue(&tq_immediate)++#else+#define ocf_iomem_t	void __iomem *++#include <linux/workqueue.h>++#endif++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)+#include <linux/fdtable.h>+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)+#define files_fdtable(files)	(files)+#endif++#ifdef MODULE_PARM+#undef module_param	/* just in case */+#define	module_param(a,b,c)		MODULE_PARM(a,"i")+#endif++#define bzero(s,l)		memset(s,0,l)+#define bcopy(s,d,l)	memcpy(d,s,l)+#define bcmp(x, y, l)	memcmp(x,y,l)++#define MIN(x,y)	((x) < (y) ? (x) : (y))++#define device_printf(dev, a...) ({ \+				printk("%s: ", device_get_nameunit(dev)); printk(a); \+			})++#undef printf+#define printf(fmt...)	printk(fmt)++#define KASSERT(c,p)	if (!(c)) { printk p ; } else++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+#define ocf_daemonize(str) \+	daemonize(); \+	spin_lock_irq(¤t->sigmask_lock); \+	sigemptyset(¤t->blocked); \+	recalc_sigpending(current); \+	spin_unlock_irq(¤t->sigmask_lock); \+	sprintf(current->comm, str);+#else+#define ocf_daemonize(str) daemonize(str);+#endif++#define	TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))+#define	TAILQ_EMPTY(q)	list_empty(q)+#define	TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)++#define read_random(p,l) get_random_bytes(p,l)++#define DELAY(x)	((x) > 2000 ? mdelay((x)/1000) : udelay(x))+#define strtoul simple_strtoul++#define pci_get_vendor(dev)	((dev)->vendor)+#define pci_get_device(dev)	((dev)->device)++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+#define pci_set_consistent_dma_mask(dev, mask) (0)+#endif+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)+#define pci_dma_sync_single_for_cpu pci_dma_sync_single+#endif++#ifndef DMA_32BIT_MASK+#define DMA_32BIT_MASK  0x00000000ffffffffULL+#endif++#ifndef htole32+#define htole32(x)	cpu_to_le32(x)+#endif+#ifndef htobe32+#define htobe32(x)	cpu_to_be32(x)+#endif+#ifndef htole16+#define htole16(x)	cpu_to_le16(x)+#endif+#ifndef htobe16+#define htobe16(x)	cpu_to_be16(x)+#endif++/* older kernels don't have these */++#include <asm/irq.h>+#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)+#define IRQ_NONE+#define IRQ_HANDLED+#define IRQ_WAKE_THREAD+#define IRQ_RETVAL+#define irqreturn_t void+typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);+#endif+#ifndef IRQF_SHARED+#define IRQF_SHARED	SA_SHIRQ+#endif++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)+# define strlcpy(dest,src,len) \+		({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })+#endif++#ifndef MAX_ERRNO+#define MAX_ERRNO	4095+#endif+#ifndef IS_ERR_VALUE+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)+#include <linux/err.h>+#endif+#ifndef IS_ERR_VALUE+#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)+#endif+#endif++/*+ * common debug for all+ */+#if 1+#define dprintk(a...)	do { if (debug) printk(a); } while(0)+#else+#define dprintk(a...)+#endif++#ifndef SLAB_ATOMIC+/* Changed in 2.6.20, must use GFP_ATOMIC now */+#define	SLAB_ATOMIC	GFP_ATOMIC+#endif++/*+ * need some additional support for older kernels */+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)+#define pci_register_driver_compat(driver, rc) \+	do { \+		if ((rc) > 0) { \+			(rc) = 0; \+		} else if (rc == 0) { \+			(rc) = -ENODEV; \+		} else { \+			pci_unregister_driver(driver); \+		} \+	} while (0)+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)+#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)+#else+#define pci_register_driver_compat(driver,rc)+#endif++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)++#include <linux/mm.h>+#include <asm/scatterlist.h>++static inline void sg_set_page(struct scatterlist *sg,  struct page *page,+			       unsigned int len, unsigned int offset)+{+	sg->page = page;+	sg->offset = offset;+	sg->length = len;+}++static inline void *sg_virt(struct scatterlist *sg)+{+	return page_address(sg->page) + sg->offset;+}++#define sg_init_table(sg, n)++#endif++#ifndef late_initcall+#define late_initcall(init) module_init(init)+#endif++#endif /* __KERNEL__ */++/****************************************************************************/+#endif /* _BSD_COMPAT_H_ */diff -Nur linux-2.6.36.orig/crypto/ocf/ocfnull/Makefile linux-2.6.36/crypto/ocf/ocfnull/Makefile--- linux-2.6.36.orig/crypto/ocf/ocfnull/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ocfnull/Makefile	2010-11-09 20:28:12.462495574 +0100@@ -0,0 +1,12 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/..++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.36/crypto/ocf/ocfnull/ocfnull.c--- linux-2.6.36.orig/crypto/ocf/ocfnull/ocfnull.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/ocfnull/ocfnull.c	2010-11-09 20:28:12.501251038 +0100@@ -0,0 +1,203 @@+/*+ * An OCF module for determining the cost of crypto versus the cost of+ * IPSec processing outside of OCF.  This modules gives us the effect of+ * zero cost encryption,  of course you will need to run it at both ends+ * since it does no crypto at all.+ *+ * Written by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough + *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this product+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/sched.h>+#include <linux/wait.h>+#include <linux/crypto.h>+#include <linux/interrupt.h>++#include <cryptodev.h>+#include <uio.h>++static int32_t			 null_id = -1;+static u_int32_t		 null_sesnum = 0;++static int null_process(device_t, struct cryptop *, int);+static int null_newsession(device_t, u_int32_t *, struct cryptoini *);+static int null_freesession(device_t, u_int64_t);++#define debug ocfnull_debug+int ocfnull_debug = 0;+module_param(ocfnull_debug, int, 0644);+MODULE_PARM_DESC(ocfnull_debug, "Enable debug");++/*+ * dummy device structure+ */++static struct {+	softc_device_decl	sc_dev;+} nulldev;++static device_method_t null_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	null_newsession),+	DEVMETHOD(cryptodev_freesession,null_freesession),+	DEVMETHOD(cryptodev_process,	null_process),+};++/*+ * Generate a new software session.+ */+static int+null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)+{+	dprintk("%s()\n", __FUNCTION__);+	if (sid == NULL || cri == NULL) {+		dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	if (null_sesnum == 0)+		null_sesnum++;+	*sid = null_sesnum++;+	return 0;+}+++/*+ * Free a session.+ */+static int+null_freesession(device_t arg, u_int64_t tid)+{+	u_int32_t sid = CRYPTO_SESID2LID(tid);++	dprintk("%s()\n", __FUNCTION__);+	if (sid > null_sesnum) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	/* Silently accept and return */+	if (sid == 0)+		return 0;+	return 0;+}+++/*+ * Process a request.+ */+static int+null_process(device_t arg, struct cryptop *crp, int hint)+{+	unsigned int lid;++	dprintk("%s()\n", __FUNCTION__);++	/* Sanity check */+	if (crp == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}++	crp->crp_etype = 0;++	if (crp->crp_desc == NULL || crp->crp_buf == NULL) {+		dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);+		crp->crp_etype = EINVAL;+		goto done;+	}++	/*+	 * find the session we are using+	 */++	lid = crp->crp_sid & 0xffffffff;+	if (lid >= null_sesnum || lid == 0) {+		crp->crp_etype = ENOENT;+		dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);+		goto done;+	}++done:+	crypto_done(crp);+	return 0;+}+++/*+ * our driver startup and shutdown routines+ */++static int+null_init(void)+{+	dprintk("%s(%p)\n", __FUNCTION__, null_init);++	memset(&nulldev, 0, sizeof(nulldev));+	softc_device_init(&nulldev, "ocfnull", 0, null_methods);++	null_id = crypto_get_driverid(softc_get_device(&nulldev),+				CRYPTOCAP_F_HARDWARE);+	if (null_id < 0)+		panic("ocfnull: crypto device cannot initialize!");++#define	REGISTER(alg) \+	crypto_register(null_id,alg,0,0)+	REGISTER(CRYPTO_DES_CBC);+	REGISTER(CRYPTO_3DES_CBC);+	REGISTER(CRYPTO_RIJNDAEL128_CBC);+	REGISTER(CRYPTO_MD5);+	REGISTER(CRYPTO_SHA1);+	REGISTER(CRYPTO_MD5_HMAC);+	REGISTER(CRYPTO_SHA1_HMAC);+#undef REGISTER++	return 0;+}++static void+null_exit(void)+{+	dprintk("%s()\n", __FUNCTION__);+	crypto_unregister_all(null_id);+	null_id = -1;+}++module_init(null_init);+module_exit(null_exit);++MODULE_LICENSE("Dual BSD/GPL");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/Makefile linux-2.6.36/crypto/ocf/pasemi/Makefile--- linux-2.6.36.orig/crypto/ocf/pasemi/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/pasemi/Makefile	2010-11-09 20:28:12.532495480 +0100@@ -0,0 +1,12 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_PASEMI) += pasemi.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.36/crypto/ocf/pasemi/pasemi.c--- linux-2.6.36.orig/crypto/ocf/pasemi/pasemi.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/pasemi/pasemi.c	2010-11-09 20:28:12.572495531 +0100@@ -0,0 +1,1009 @@+/*+ * Copyright (C) 2007 PA Semi, Inc+ *+ * Driver for the PA Semi PWRficient DMA Crypto Engine+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/interrupt.h>+#include <linux/timer.h>+#include <linux/random.h>+#include <linux/skbuff.h>+#include <asm/scatterlist.h>+#include <linux/moduleparam.h>+#include <linux/pci.h>+#include <cryptodev.h>+#include <uio.h>+#include "pasemi_fnu.h"++#define DRV_NAME "pasemi"++#define TIMER_INTERVAL 1000++static void __devexit pasemi_dma_remove(struct pci_dev *pdev);+static struct pasdma_status volatile * dma_status;++static int debug;+module_param(debug, int, 0644);+MODULE_PARM_DESC(debug, "Enable debug");++static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)+{+	desc->postop = 0;+	desc->quad[0] = hdr;+	desc->quad_cnt = 1;+	desc->size = 1;+}++static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)+{+	desc->quad[desc->quad_cnt++] = val;+	desc->size = (desc->quad_cnt + 1) / 2;+}++static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)+{+	desc->quad[0] |= hdr;+}++static int pasemi_desc_size(struct pasemi_desc *desc)+{+	return desc->size;+}++static void pasemi_ring_add_desc(+				 struct pasemi_fnu_txring *ring,+				 struct pasemi_desc *desc,+				 struct cryptop *crp) {+	int i;+	int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));++	TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;+	TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;+	TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;++	for (i = 0; i < desc->quad_cnt; i += 2) {+		ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));+		ring->desc[ring_index] = desc->quad[i];+		ring->desc[ring_index + 1] = desc->quad[i + 1];+		ring->next_to_fill++;+	}++	if (desc->quad_cnt & 1)+		ring->desc[ring_index + 1] = 0;+}++static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)+{+	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),+		 incr);+}++/*+ * Generate a new software session.+ */+static int+pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)+{+	struct cryptoini *c, *encini = NULL, *macini = NULL;+	struct pasemi_softc *sc = device_get_softc(dev);+	struct pasemi_session *ses = NULL, **sespp;+	int sesn, blksz = 0;+	u64 ccmd = 0;+	unsigned long flags;+	struct pasemi_desc init_desc;+	struct pasemi_fnu_txring *txring;++	DPRINTF("%s()\n", __FUNCTION__);+	if (sidp == NULL || cri == NULL || sc == NULL) {+		DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return -EINVAL;+	}+	for (c = cri; c != NULL; c = c->cri_next) {+		if (ALG_IS_SIG(c->cri_alg)) {+			if (macini)+				return -EINVAL;+			macini = c;+		} else if (ALG_IS_CIPHER(c->cri_alg)) {+			if (encini)+				return -EINVAL;+			encini = c;+		} else {+			DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);+			return -EINVAL;+		}+	}+	if (encini == NULL && macini == NULL)+		return -EINVAL;+	if (encini) {+		/* validate key length */+		switch (encini->cri_alg) {+		case CRYPTO_DES_CBC:+			if (encini->cri_klen != 64)+				return -EINVAL;+			ccmd = DMA_CALGO_DES;+			break;+		case CRYPTO_3DES_CBC:+			if (encini->cri_klen != 192)+				return -EINVAL;+			ccmd = DMA_CALGO_3DES;+			break;+		case CRYPTO_AES_CBC:+			if (encini->cri_klen != 128 &&+			    encini->cri_klen != 192 &&+			    encini->cri_klen != 256)+				return -EINVAL;+			ccmd = DMA_CALGO_AES;+			break;+		case CRYPTO_ARC4:+			if (encini->cri_klen != 128)+				return -EINVAL;+			ccmd = DMA_CALGO_ARC;+			break;+		default:+			DPRINTF("UNKNOWN encini->cri_alg %d\n",+				encini->cri_alg);+			return -EINVAL;+		}+	}++	if (macini) {+		switch (macini->cri_alg) {+		case CRYPTO_MD5:+		case CRYPTO_MD5_HMAC:+			blksz = 16;+			break;+		case CRYPTO_SHA1:+		case CRYPTO_SHA1_HMAC:+			blksz = 20;+			break;+		default:+			DPRINTF("UNKNOWN macini->cri_alg %d\n",+				macini->cri_alg);+			return -EINVAL;+		}+		if (((macini->cri_klen + 7) / 8) > blksz) {+			DPRINTF("key length %d bigger than blksize %d not supported\n",+				((macini->cri_klen + 7) / 8), blksz);+			return -EINVAL;+		}+	}++	for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {+		if (sc->sc_sessions[sesn] == NULL) {+			sc->sc_sessions[sesn] = (struct pasemi_session *)+				kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);+			ses = sc->sc_sessions[sesn];+			break;+		} else if (sc->sc_sessions[sesn]->used == 0) {+			ses = sc->sc_sessions[sesn];+			break;+		}+	}++	if (ses == NULL) {+		sespp = (struct pasemi_session **)+			kzalloc(sc->sc_nsessions * 2 *+				sizeof(struct pasemi_session *), GFP_ATOMIC);+		if (sespp == NULL)+			return -ENOMEM;+		memcpy(sespp, sc->sc_sessions,+		       sc->sc_nsessions * sizeof(struct pasemi_session *));+		kfree(sc->sc_sessions);+		sc->sc_sessions = sespp;+		sesn = sc->sc_nsessions;+		ses = sc->sc_sessions[sesn] = (struct pasemi_session *)+			kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);+		if (ses == NULL)+			return -ENOMEM;+		sc->sc_nsessions *= 2;+	}++	ses->used = 1;++	ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,+				       sizeof(struct pasemi_session), DMA_TO_DEVICE);++	/* enter the channel scheduler */+	spin_lock_irqsave(&sc->sc_chnlock, flags);++	/* ARC4 has to be processed by the even channel */+	if (encini && (encini->cri_alg == CRYPTO_ARC4))+		ses->chan = sc->sc_lastchn & ~1;+	else+		ses->chan = sc->sc_lastchn;+	sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;++	spin_unlock_irqrestore(&sc->sc_chnlock, flags);++	txring = &sc->tx[ses->chan];++	if (encini) {+		ses->ccmd = ccmd;++		/* get an IV */+		/* XXX may read fewer than requested */+		get_random_bytes(ses->civ, sizeof(ses->civ));++		ses->keysz = (encini->cri_klen - 63) / 64;+		memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);++		pasemi_desc_start(&init_desc,+				  XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));+		pasemi_desc_build(&init_desc,+				  XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));+	}+	if (macini) {+		if (macini->cri_alg == CRYPTO_MD5_HMAC ||+		    macini->cri_alg == CRYPTO_SHA1_HMAC)+			memcpy(ses->hkey, macini->cri_key, blksz);+		else {+			/* Load initialization constants(RFC 1321, 3174) */+			ses->hiv[0] = 0x67452301efcdab89ULL;+			ses->hiv[1] = 0x98badcfe10325476ULL;+			ses->hiv[2] = 0xc3d2e1f000000000ULL;+		}+		ses->hseq = 0ULL;+	}++	spin_lock_irqsave(&txring->fill_lock, flags);++	if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -+	     txring->next_to_clean) > TX_RING_SIZE) {+		spin_unlock_irqrestore(&txring->fill_lock, flags);+		return ERESTART;+	}++	if (encini) {+		pasemi_ring_add_desc(txring, &init_desc, NULL);+		pasemi_ring_incr(sc, ses->chan,+				 pasemi_desc_size(&init_desc));+	}++	txring->sesn = sesn;+	spin_unlock_irqrestore(&txring->fill_lock, flags);++	*sidp = PASEMI_SID(sesn);+	return 0;+}++/*+ * Deallocate a session.+ */+static int+pasemi_freesession(device_t dev, u_int64_t tid)+{+	struct pasemi_softc *sc = device_get_softc(dev);+	int session;+	u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;++	DPRINTF("%s()\n", __FUNCTION__);++	if (sc == NULL)+		return -EINVAL;+	session = PASEMI_SESSION(sid);+	if (session >= sc->sc_nsessions || !sc->sc_sessions[session])+		return -EINVAL;++	pci_unmap_single(sc->dma_pdev,+			 sc->sc_sessions[session]->dma_addr,+			 sizeof(struct pasemi_session), DMA_TO_DEVICE);+	memset(sc->sc_sessions[session], 0,+	       sizeof(struct pasemi_session));++	return 0;+}++static int+pasemi_process(device_t dev, struct cryptop *crp, int hint)+{++	int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;+	struct pasemi_softc *sc = device_get_softc(dev);+	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;+	caddr_t ivp;+	struct pasemi_desc init_desc, work_desc;+	struct pasemi_session *ses;+	struct sk_buff *skb;+	struct uio *uiop;+	unsigned long flags;+	struct pasemi_fnu_txring *txring;++	DPRINTF("%s()\n", __FUNCTION__);++	if (crp == NULL || crp->crp_callback == NULL || sc == NULL)+		return -EINVAL;++	crp->crp_etype = 0;+	if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)+		return -EINVAL;++	ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];++	crd1 = crp->crp_desc;+	if (crd1 == NULL) {+		err = -EINVAL;+		goto errout;+	}+	crd2 = crd1->crd_next;++	if (ALG_IS_SIG(crd1->crd_alg)) {+		maccrd = crd1;+		if (crd2 == NULL)+			enccrd = NULL;+		else if (ALG_IS_CIPHER(crd2->crd_alg) &&+			 (crd2->crd_flags & CRD_F_ENCRYPT) == 0)+			enccrd = crd2;+		else+			goto erralg;+	} else if (ALG_IS_CIPHER(crd1->crd_alg)) {+		enccrd = crd1;+		if (crd2 == NULL)+			maccrd = NULL;+		else if (ALG_IS_SIG(crd2->crd_alg) &&+			 (crd1->crd_flags & CRD_F_ENCRYPT))+			maccrd = crd2;+		else+			goto erralg;+	} else+		goto erralg;++	chsel = ses->chan;++	txring = &sc->tx[chsel];++	if (enccrd && !maccrd) {+		if (enccrd->crd_alg == CRYPTO_ARC4)+			reinit = 1;+		reinit_size = 0x40;+		srclen = crp->crp_ilen;++		pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I+				  | XCT_FUN_FUN(chsel));+		if (enccrd->crd_flags & CRD_F_ENCRYPT)+			pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);+		else+			pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);+	} else if (enccrd && maccrd) {+		if (enccrd->crd_alg == CRYPTO_ARC4)+			reinit = 1;+		reinit_size = 0x68;++		if (enccrd->crd_flags & CRD_F_ENCRYPT) {+			/* Encrypt -> Authenticate */+			pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG+					  | XCT_FUN_A | XCT_FUN_FUN(chsel));+			srclen = maccrd->crd_skip + maccrd->crd_len;+		} else {+			/* Authenticate -> Decrypt */+			pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC+					  | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));+			pasemi_desc_build(&work_desc, 0);+			pasemi_desc_build(&work_desc, 0);+			pasemi_desc_build(&work_desc, 0);+			work_desc.postop = PASEMI_CHECK_SIG;+			srclen = crp->crp_ilen;+		}++		pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));+		pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));+	} else if (!enccrd && maccrd) {+		srclen = maccrd->crd_len;++		pasemi_desc_start(&init_desc,+				  XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));+		pasemi_desc_build(&init_desc,+				  XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));++		pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG+				  | XCT_FUN_A | XCT_FUN_FUN(chsel));+	}++	if (enccrd) {+		switch (enccrd->crd_alg) {+		case CRYPTO_3DES_CBC:+			pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |+					XCT_FUN_BCM_CBC);+			ivsize = sizeof(u64);+			break;+		case CRYPTO_DES_CBC:+			pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |+					XCT_FUN_BCM_CBC);+			ivsize = sizeof(u64);+			break;+		case CRYPTO_AES_CBC:+			pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |+					XCT_FUN_BCM_CBC);+			ivsize = 2 * sizeof(u64);+			break;+		case CRYPTO_ARC4:+			pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);+			ivsize = 0;+			break;+		default:+			printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",+			       enccrd->crd_alg);+			err = -EINVAL;+			goto errout;+		}++		ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];+		if (enccrd->crd_flags & CRD_F_ENCRYPT) {+			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)+				memcpy(ivp, enccrd->crd_iv, ivsize);+			/* If IV is not present in the buffer already, it has to be copied there */+			if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)+				crypto_copyback(crp->crp_flags, crp->crp_buf,+						enccrd->crd_inject, ivsize, ivp);+		} else {+			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)+				/* IV is provided expicitly in descriptor */+				memcpy(ivp, enccrd->crd_iv, ivsize);+			else+				/* IV is provided in the packet */+				crypto_copydata(crp->crp_flags, crp->crp_buf,+						enccrd->crd_inject, ivsize,+						ivp);+		}+	}++	if (maccrd) {+		switch (maccrd->crd_alg) {+		case CRYPTO_MD5:+			pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |+					XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));+			break;+		case CRYPTO_SHA1:+			pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |+					XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));+			break;+		case CRYPTO_MD5_HMAC:+			pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |+					XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));+			break;+		case CRYPTO_SHA1_HMAC:+			pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |+					XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));+			break;+		default:+			printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",+			       maccrd->crd_alg);+			err = -EINVAL;+			goto errout;+		}+	}++	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		/* using SKB buffers */+		skb = (struct sk_buff *)crp->crp_buf;+		if (skb_shinfo(skb)->nr_frags) {+			printk(DRV_NAME ": skb frags unimplemented\n");+			err = -EINVAL;+			goto errout;+		}+		pasemi_desc_build(+			&work_desc,+			XCT_FUN_DST_PTR(skb->len, pci_map_single(+						sc->dma_pdev, skb->data,+						skb->len, DMA_TO_DEVICE)));+		pasemi_desc_build(+			&work_desc,+			XCT_FUN_SRC_PTR(+				srclen, pci_map_single(+					sc->dma_pdev, skb->data,+					srclen, DMA_TO_DEVICE)));+		pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		/* using IOV buffers */+		uiop = (struct uio *)crp->crp_buf;+		if (uiop->uio_iovcnt > 1) {+			printk(DRV_NAME ": iov frags unimplemented\n");+			err = -EINVAL;+			goto errout;+		}++		/* crp_olen is never set; always use crp_ilen */+		pasemi_desc_build(+			&work_desc,+			XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(+						sc->dma_pdev,+						uiop->uio_iov->iov_base,+						crp->crp_ilen, DMA_TO_DEVICE)));+		pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));++		pasemi_desc_build(+			&work_desc,+			XCT_FUN_SRC_PTR(srclen, pci_map_single(+						sc->dma_pdev,+						uiop->uio_iov->iov_base,+						srclen, DMA_TO_DEVICE)));+	} else {+		/* using contig buffers */+		pasemi_desc_build(+			&work_desc,+			XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(+						sc->dma_pdev,+						crp->crp_buf,+						crp->crp_ilen, DMA_TO_DEVICE)));+		pasemi_desc_build(+			&work_desc,+			XCT_FUN_SRC_PTR(srclen, pci_map_single(+						sc->dma_pdev,+						crp->crp_buf, srclen,+						DMA_TO_DEVICE)));+		pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));+	}++	spin_lock_irqsave(&txring->fill_lock, flags);++	if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {+		txring->sesn = PASEMI_SESSION(crp->crp_sid);+		reinit = 1;+	}++	if (enccrd) {+		pasemi_desc_start(&init_desc,+				  XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));+		pasemi_desc_build(&init_desc,+				  XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));+	}++	if (((txring->next_to_fill + pasemi_desc_size(&init_desc) ++	      pasemi_desc_size(&work_desc)) -+	     txring->next_to_clean) > TX_RING_SIZE) {+		spin_unlock_irqrestore(&txring->fill_lock, flags);+		err = ERESTART;+		goto errout;+	}++	pasemi_ring_add_desc(txring, &init_desc, NULL);+	pasemi_ring_add_desc(txring, &work_desc, crp);++	pasemi_ring_incr(sc, chsel,+			 pasemi_desc_size(&init_desc) ++			 pasemi_desc_size(&work_desc));++	spin_unlock_irqrestore(&txring->fill_lock, flags);++	mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);++	return 0;++erralg:+	printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",+	       crd1->crd_alg, crd2->crd_alg);+	err = -EINVAL;++errout:+	if (err != ERESTART) {+		crp->crp_etype = err;+		crypto_done(crp);+	}+	return err;+}++static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)+{+	int i, j, ring_idx;+	struct pasemi_fnu_txring *ring = &sc->tx[chan];+	u16 delta_cnt;+	int flags, loops = 10;+	int desc_size;+	struct cryptop *crp;++	spin_lock_irqsave(&ring->clean_lock, flags);++	while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]+			     & PAS_STATUS_PCNT_M) - ring->total_pktcnt)+	       && loops--) {++		for (i = 0; i < delta_cnt; i++) {+			desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;+			crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;+			if (crp) {+				ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));+				if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {+					/* Need to make sure signature matched,+					 * if not - return error */+					if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))+						crp->crp_etype = -EINVAL;+				}+				crypto_done(TX_DESC_INFO(ring,+							 ring->next_to_clean).cf_crp);+				TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;+				pci_unmap_single(+					sc->dma_pdev,+					XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),+					PCI_DMA_TODEVICE);++				ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;++				ring->next_to_clean++;+				for (j = 1; j < desc_size; j++) {+					ring_idx = 2 *+						(ring->next_to_clean &+						 (TX_RING_SIZE-1));+					pci_unmap_single(+						sc->dma_pdev,+						XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),+						PCI_DMA_TODEVICE);+					if (ring->desc[ring_idx + 1])+						pci_unmap_single(+							sc->dma_pdev,+							XCT_PTR_ADDR_LEN(+								ring->desc[+									ring_idx + 1]),+							PCI_DMA_TODEVICE);+					ring->desc[ring_idx] =+						ring->desc[ring_idx + 1] = 0;+					ring->next_to_clean++;+				}+			} else {+				for (j = 0; j < desc_size; j++) {+					ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));+					ring->desc[ring_idx] =+						ring->desc[ring_idx + 1] = 0;+					ring->next_to_clean++;+				}+			}+		}++		ring->total_pktcnt += delta_cnt;+	}+	spin_unlock_irqrestore(&ring->clean_lock, flags);++	return 0;+}++static void sweepup_tx(struct pasemi_softc *sc)+{+	int i;++	for (i = 0; i < sc->sc_num_channels; i++)+		pasemi_clean_tx(sc, i);+}++static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)+{+	struct pasemi_softc *sc = arg;+	unsigned int reg;+	int chan = irq - sc->base_irq;+	int chan_index = sc->base_chan + chan;+	u64 stat = dma_status->tx_sta[chan_index];++	DPRINTF("%s()\n", __FUNCTION__);++	if (!(stat & PAS_STATUS_CAUSE_M))+		return IRQ_NONE;++	pasemi_clean_tx(sc, chan);++	stat = dma_status->tx_sta[chan_index];++	reg = PAS_IOB_DMA_TXCH_RESET_PINTC |+		PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);++	if (stat & PAS_STATUS_SOFT)+		reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;++	out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);+++	return IRQ_HANDLED;+}++static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)+{+	u32 val;+	int chan_index = chan + sc->base_chan;+	int ret;+	struct pasemi_fnu_txring *ring;++	ring = &sc->tx[chan];++	spin_lock_init(&ring->fill_lock);+	spin_lock_init(&ring->clean_lock);++	ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *+				  TX_RING_SIZE, GFP_KERNEL);+	if (!ring->desc_info)+		return -ENOMEM;++	/* Allocate descriptors */+	ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,+					TX_RING_SIZE *+					2 * sizeof(u64),+					&ring->dma, GFP_KERNEL);+	if (!ring->desc)+		return -ENOMEM;++	memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));++	out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);++	ring->total_pktcnt = 0;++	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),+		 PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));++	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);+	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);++	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);++	out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),+		 PAS_DMA_TXCHAN_CFG_TY_FUNC |+		 PAS_DMA_TXCHAN_CFG_TATTR(chan) |+		 PAS_DMA_TXCHAN_CFG_WT(2));++	/* enable tx channel */+	out_le32(sc->dma_regs ++		 PAS_DMA_TXCHAN_TCMDSTA(chan_index),+		 PAS_DMA_TXCHAN_TCMDSTA_EN);++	out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),+		 PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));++	ring->next_to_fill = 0;+	ring->next_to_clean = 0;++	snprintf(ring->irq_name, sizeof(ring->irq_name),+		 "%s%d", "crypto", chan);++	ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);+	ret = request_irq(ring->irq, (irq_handler_t)+			  pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);+	if (ret) {+		printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",+		       ring->irq, ret);+		ring->irq = -1;+		return ret;+	}++	setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);++	return 0;+}++static device_method_t pasemi_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,		pasemi_newsession),+	DEVMETHOD(cryptodev_freesession,	pasemi_freesession),+	DEVMETHOD(cryptodev_process,		pasemi_process),+};++/* Set up the crypto device structure, private data,+ * and anything else we need before we start */++static int __devinit+pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)+{+	struct pasemi_softc *sc;+	int ret, i;++	DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);++	sc = kzalloc(sizeof(*sc), GFP_KERNEL);+	if (!sc)+		return -ENOMEM;++	softc_device_init(sc, DRV_NAME, 1, pasemi_methods);++	pci_set_drvdata(pdev, sc);++	spin_lock_init(&sc->sc_chnlock);++	sc->sc_sessions = (struct pasemi_session **)+		kzalloc(PASEMI_INITIAL_SESSIONS *+			sizeof(struct pasemi_session *), GFP_ATOMIC);+	if (sc->sc_sessions == NULL) {+		ret = -ENOMEM;+		goto out;+	}++	sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;+	sc->sc_lastchn = 0;+	sc->base_irq = pdev->irq + 6;+	sc->base_chan = 6;+	sc->sc_cid = -1;+	sc->dma_pdev = pdev;++	sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);+	if (!sc->iob_pdev) {+		dev_err(&pdev->dev, "Can't find I/O Bridge\n");+		ret = -ENODEV;+		goto out;+	}++	/* This is hardcoded and ugly, but we have some firmware versions+	 * who don't provide the register space in the device tree. Luckily+	 * they are at well-known locations so we can just do the math here.+	 */+	sc->dma_regs =+		ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);+	sc->iob_regs =+		ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);+	if (!sc->dma_regs || !sc->iob_regs) {+		dev_err(&pdev->dev, "Can't map registers\n");+		ret = -ENODEV;+		goto out;+	}++	dma_status = __ioremap(0xfd800000, 0x1000, 0);+	if (!dma_status) {+		ret = -ENODEV;+		dev_err(&pdev->dev, "Can't map dmastatus space\n");+		goto out;+	}++	sc->tx = (struct pasemi_fnu_txring *)+		kzalloc(sizeof(struct pasemi_fnu_txring)+			* 8, GFP_KERNEL);+	if (!sc->tx) {+		ret = -ENOMEM;+		goto out;+	}++	/* Initialize the h/w */+	out_le32(sc->dma_regs + PAS_DMA_COM_CFG,+		 (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |+		  PAS_DMA_COM_CFG_FWF));+	out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);++	for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {+		sc->sc_num_channels++;+		ret = pasemi_dma_setup_tx_resources(sc, i);+		if (ret)+			goto out;+	}++	sc->sc_cid = crypto_get_driverid(softc_get_device(sc),+					 CRYPTOCAP_F_HARDWARE);+	if (sc->sc_cid < 0) {+		printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");+		ret = -ENXIO;+		goto out;+	}++	/* register algorithms with the framework */+	printk(DRV_NAME ":");++	crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);++	return 0;++out:+	pasemi_dma_remove(pdev);+	return ret;+}++#define MAX_RETRIES 5000++static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)+{+	struct pasemi_fnu_txring *ring = &sc->tx[chan];+	int chan_index = chan + sc->base_chan;+	int retries;+	u32 stat;++	/* Stop the channel */+	out_le32(sc->dma_regs ++		 PAS_DMA_TXCHAN_TCMDSTA(chan_index),+		 PAS_DMA_TXCHAN_TCMDSTA_ST);++	for (retries = 0; retries < MAX_RETRIES; retries++) {+		stat = in_le32(sc->dma_regs ++			       PAS_DMA_TXCHAN_TCMDSTA(chan_index));+		if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))+			break;+		cond_resched();+	}++	if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)+		dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",+			chan_index);++	/* Disable the channel */+	out_le32(sc->dma_regs ++		 PAS_DMA_TXCHAN_TCMDSTA(chan_index),+		 0);++	if (ring->desc_info)+		kfree((void *) ring->desc_info);+	if (ring->desc)+		dma_free_coherent(&sc->dma_pdev->dev,+				  TX_RING_SIZE *+				  2 * sizeof(u64),+				  (void *) ring->desc, ring->dma);+	if (ring->irq != -1)+		free_irq(ring->irq, sc);++	del_timer(&ring->crypto_timer);+}++static void __devexit pasemi_dma_remove(struct pci_dev *pdev)+{+	struct pasemi_softc *sc = pci_get_drvdata(pdev);+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	if (sc->sc_cid >= 0) {+		crypto_unregister_all(sc->sc_cid);+	}++	if (sc->tx) {+		for (i = 0; i < sc->sc_num_channels; i++)+			pasemi_free_tx_resources(sc, i);++		kfree(sc->tx);+	}+	if (sc->sc_sessions) {+		for (i = 0; i < sc->sc_nsessions; i++)+			kfree(sc->sc_sessions[i]);+		kfree(sc->sc_sessions);+	}+	if (sc->iob_pdev)+		pci_dev_put(sc->iob_pdev);+	if (sc->dma_regs)+		iounmap(sc->dma_regs);+	if (sc->iob_regs)+		iounmap(sc->iob_regs);+	kfree(sc);+}++static struct pci_device_id pasemi_dma_pci_tbl[] = {+	{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },+};++MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);++static struct pci_driver pasemi_dma_driver = {+	.name		= "pasemi_dma",+	.id_table	= pasemi_dma_pci_tbl,+	.probe		= pasemi_dma_probe,+	.remove		= __devexit_p(pasemi_dma_remove),+};++static void __exit pasemi_dma_cleanup_module(void)+{+	pci_unregister_driver(&pasemi_dma_driver);+	__iounmap(dma_status);+	dma_status = NULL;+}++int pasemi_dma_init_module(void)+{+	return pci_register_driver(&pasemi_dma_driver);+}++module_init(pasemi_dma_init_module);+module_exit(pasemi_dma_cleanup_module);++MODULE_LICENSE("Dual BSD/GPL");+MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");+MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");diff -Nur linux-2.6.36.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.36/crypto/ocf/pasemi/pasemi_fnu.h--- linux-2.6.36.orig/crypto/ocf/pasemi/pasemi_fnu.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/pasemi/pasemi_fnu.h	2010-11-09 20:28:12.612495424 +0100@@ -0,0 +1,410 @@+/*+ * Copyright (C) 2007 PA Semi, Inc+ *+ * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and+ * hardware register layouts.+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License version 2 as+ * published by the Free Software Foundation.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA+ */++#ifndef PASEMI_FNU_H+#define PASEMI_FNU_H++#include <linux/spinlock.h>++#define	PASEMI_SESSION(sid)	((sid) & 0xffffffff)+#define	PASEMI_SID(sesn)	((sesn) & 0xffffffff)+#define	DPRINTF(a...)	if (debug) { printk(DRV_NAME ": " a); }++/* Must be a power of two */+#define RX_RING_SIZE 512+#define TX_RING_SIZE 512+#define TX_DESC(ring, num)	((ring)->desc[2 * (num & (TX_RING_SIZE-1))])+#define TX_DESC_INFO(ring, num)	((ring)->desc_info[(num) & (TX_RING_SIZE-1)])+#define MAX_DESC_SIZE 8+#define PASEMI_INITIAL_SESSIONS 10+#define PASEMI_FNU_CHANNELS 8++/* DMA descriptor */+struct pasemi_desc {+	u64 quad[2*MAX_DESC_SIZE];+	int quad_cnt;+	int size;+	int postop;+};++/*+ * Holds per descriptor data+ */+struct pasemi_desc_info {+	int			desc_size;+	int			desc_postop;+#define PASEMI_CHECK_SIG 0x1++	struct cryptop          *cf_crp;+};++/*+ * Holds per channel data+ */+struct pasemi_fnu_txring {+	volatile u64		*desc;+	volatile struct+	pasemi_desc_info	*desc_info;+	dma_addr_t		dma;+	struct timer_list       crypto_timer;+	spinlock_t		fill_lock;+	spinlock_t		clean_lock;+	unsigned int		next_to_fill;+	unsigned int		next_to_clean;+	u16			total_pktcnt;+	int			irq;+	int			sesn;+	char			irq_name[10];+};++/*+ * Holds data specific to a single pasemi device.+ */+struct pasemi_softc {+	softc_device_decl	sc_cdev;+	struct pci_dev		*dma_pdev;	/* device backpointer */+	struct pci_dev		*iob_pdev;	/* device backpointer */+	void __iomem		*dma_regs;+	void __iomem		*iob_regs;+	int			base_irq;+	int			base_chan;+	int32_t			sc_cid;		/* crypto tag */+	int			sc_nsessions;+	struct pasemi_session	**sc_sessions;+	int			sc_num_channels;/* number of crypto channels */++	/* pointer to the array of txring datastructures, one txring per channel */+	struct pasemi_fnu_txring *tx;++	/*+	 * mutual exclusion for the channel scheduler+	 */+	spinlock_t		sc_chnlock;+	/* last channel used, for now use round-robin to allocate channels */+	int			sc_lastchn;+};++struct pasemi_session {+	u64 civ[2];+	u64 keysz;+	u64 key[4];+	u64 ccmd;+	u64 hkey[4];+	u64 hseq;+	u64 giv[2];+	u64 hiv[4];++	int used;+	dma_addr_t	dma_addr;+	int chan;+};++/* status register layout in IOB region, at 0xfd800000 */+struct pasdma_status {+	u64 rx_sta[64];+	u64 tx_sta[20];+};++#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC)		|| \+				(alg == CRYPTO_3DES_CBC)	|| \+				(alg == CRYPTO_AES_CBC)		|| \+				(alg == CRYPTO_ARC4)		|| \+				(alg == CRYPTO_NULL_CBC))++#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5)			|| \+				(alg == CRYPTO_MD5_HMAC)	|| \+				(alg == CRYPTO_SHA1)		|| \+				(alg == CRYPTO_SHA1_HMAC)	|| \+				(alg == CRYPTO_NULL_HMAC))++enum {+	PAS_DMA_COM_TXCMD = 0x100,	/* Transmit Command Register  */+	PAS_DMA_COM_TXSTA = 0x104,	/* Transmit Status Register   */+	PAS_DMA_COM_RXCMD = 0x108,	/* Receive Command Register   */+	PAS_DMA_COM_RXSTA = 0x10c,	/* Receive Status Register    */+	PAS_DMA_COM_CFG   = 0x114,	/* DMA Configuration Register */+};++/* All these registers live in the PCI configuration space for the DMA PCI+ * device. Use the normal PCI config access functions for them.+ */++#define PAS_DMA_COM_CFG_FWF	0x18000000++#define PAS_DMA_COM_TXCMD_EN	0x00000001 /* enable */+#define PAS_DMA_COM_TXSTA_ACT	0x00000001 /* active */+#define PAS_DMA_COM_RXCMD_EN	0x00000001 /* enable */+#define PAS_DMA_COM_RXSTA_ACT	0x00000001 /* active */++#define _PAS_DMA_TXCHAN_STRIDE	0x20    /* Size per channel		*/+#define _PAS_DMA_TXCHAN_TCMDSTA	0x300	/* Command / Status		*/+#define _PAS_DMA_TXCHAN_CFG	0x304	/* Configuration		*/+#define _PAS_DMA_TXCHAN_DSCRBU	0x308	/* Descriptor BU Allocation	*/+#define _PAS_DMA_TXCHAN_INCR	0x310	/* Descriptor increment		*/+#define _PAS_DMA_TXCHAN_CNT	0x314	/* Descriptor count/offset	*/+#define _PAS_DMA_TXCHAN_BASEL	0x318	/* Descriptor ring base (low)	*/+#define _PAS_DMA_TXCHAN_BASEU	0x31c	/*			(high)	*/+#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)+#define    PAS_DMA_TXCHAN_TCMDSTA_EN	0x00000001	/* Enabled */+#define    PAS_DMA_TXCHAN_TCMDSTA_ST	0x00000002	/* Stop interface */+#define    PAS_DMA_TXCHAN_TCMDSTA_ACT	0x00010000	/* Active */+#define PAS_DMA_TXCHAN_CFG(c)     (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)+#define    PAS_DMA_TXCHAN_CFG_TY_FUNC	0x00000002	/* Type = interface */+#define    PAS_DMA_TXCHAN_CFG_TY_IFACE	0x00000000	/* Type = interface */+#define    PAS_DMA_TXCHAN_CFG_TATTR_M	0x0000003c+#define    PAS_DMA_TXCHAN_CFG_TATTR_S	2+#define    PAS_DMA_TXCHAN_CFG_TATTR(x)	(((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \+					 PAS_DMA_TXCHAN_CFG_TATTR_M)+#define    PAS_DMA_TXCHAN_CFG_WT_M	0x000001c0+#define    PAS_DMA_TXCHAN_CFG_WT_S	6+#define    PAS_DMA_TXCHAN_CFG_WT(x)	(((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \+					 PAS_DMA_TXCHAN_CFG_WT_M)+#define    PAS_DMA_TXCHAN_CFG_LPSQ_FAST	0x00000400+#define    PAS_DMA_TXCHAN_CFG_LPDQ_FAST	0x00000800+#define    PAS_DMA_TXCHAN_CFG_CF	0x00001000	/* Clean first line */+#define    PAS_DMA_TXCHAN_CFG_CL	0x00002000	/* Clean last line */+#define    PAS_DMA_TXCHAN_CFG_UP	0x00004000	/* update tx descr when sent */+#define PAS_DMA_TXCHAN_INCR(c)    (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)+#define PAS_DMA_TXCHAN_BASEL(c)   (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)+#define    PAS_DMA_TXCHAN_BASEL_BRBL_M	0xffffffc0+#define    PAS_DMA_TXCHAN_BASEL_BRBL_S	0+#define    PAS_DMA_TXCHAN_BASEL_BRBL(x)	(((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \+					 PAS_DMA_TXCHAN_BASEL_BRBL_M)+#define PAS_DMA_TXCHAN_BASEU(c)   (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)+#define    PAS_DMA_TXCHAN_BASEU_BRBH_M	0x00000fff+#define    PAS_DMA_TXCHAN_BASEU_BRBH_S	0+#define    PAS_DMA_TXCHAN_BASEU_BRBH(x)	(((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \+					 PAS_DMA_TXCHAN_BASEU_BRBH_M)+/* # of cache lines worth of buffer ring */+#define    PAS_DMA_TXCHAN_BASEU_SIZ_M	0x3fff0000+#define    PAS_DMA_TXCHAN_BASEU_SIZ_S	16		/* 0 = 16K */+#define    PAS_DMA_TXCHAN_BASEU_SIZ(x)	(((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \+					 PAS_DMA_TXCHAN_BASEU_SIZ_M)++#define    PAS_STATUS_PCNT_M		0x000000000000ffffull+#define    PAS_STATUS_PCNT_S		0+#define    PAS_STATUS_DCNT_M		0x00000000ffff0000ull+#define    PAS_STATUS_DCNT_S		16+#define    PAS_STATUS_BPCNT_M		0x0000ffff00000000ull+#define    PAS_STATUS_BPCNT_S		32+#define    PAS_STATUS_CAUSE_M		0xf000000000000000ull+#define    PAS_STATUS_TIMER		0x1000000000000000ull+#define    PAS_STATUS_ERROR		0x2000000000000000ull+#define    PAS_STATUS_SOFT		0x4000000000000000ull+#define    PAS_STATUS_INT		0x8000000000000000ull++#define PAS_IOB_DMA_RXCH_CFG(i)		(0x1100 + (i)*4)+#define    PAS_IOB_DMA_RXCH_CFG_CNTTH_M		0x00000fff+#define    PAS_IOB_DMA_RXCH_CFG_CNTTH_S		0+#define    PAS_IOB_DMA_RXCH_CFG_CNTTH(x)	(((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \+						 PAS_IOB_DMA_RXCH_CFG_CNTTH_M)+#define PAS_IOB_DMA_TXCH_CFG(i)		(0x1200 + (i)*4)+#define    PAS_IOB_DMA_TXCH_CFG_CNTTH_M		0x00000fff+#define    PAS_IOB_DMA_TXCH_CFG_CNTTH_S		0+#define    PAS_IOB_DMA_TXCH_CFG_CNTTH(x)	(((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \+						 PAS_IOB_DMA_TXCH_CFG_CNTTH_M)+#define PAS_IOB_DMA_RXCH_STAT(i)	(0x1300 + (i)*4)+#define    PAS_IOB_DMA_RXCH_STAT_INTGEN	0x00001000+#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL_M	0x00000fff+#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL_S	0+#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL(x)	(((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\+						 PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)+#define PAS_IOB_DMA_TXCH_STAT(i)	(0x1400 + (i)*4)+#define    PAS_IOB_DMA_TXCH_STAT_INTGEN	0x00001000+#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL_M	0x00000fff+#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL_S	0+#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL(x)	(((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\+						 PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)+#define PAS_IOB_DMA_RXCH_RESET(i)	(0x1500 + (i)*4)+#define    PAS_IOB_DMA_RXCH_RESET_PCNT_M	0xffff0000+#define    PAS_IOB_DMA_RXCH_RESET_PCNT_S	16+#define    PAS_IOB_DMA_RXCH_RESET_PCNT(x)	(((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \+						 PAS_IOB_DMA_RXCH_RESET_PCNT_M)+#define    PAS_IOB_DMA_RXCH_RESET_PCNTRST	0x00000020+#define    PAS_IOB_DMA_RXCH_RESET_DCNTRST	0x00000010+#define    PAS_IOB_DMA_RXCH_RESET_TINTC		0x00000008+#define    PAS_IOB_DMA_RXCH_RESET_DINTC		0x00000004+#define    PAS_IOB_DMA_RXCH_RESET_SINTC		0x00000002+#define    PAS_IOB_DMA_RXCH_RESET_PINTC		0x00000001+#define PAS_IOB_DMA_TXCH_RESET(i)	(0x1600 + (i)*4)+#define    PAS_IOB_DMA_TXCH_RESET_PCNT_M	0xffff0000+#define    PAS_IOB_DMA_TXCH_RESET_PCNT_S	16+#define    PAS_IOB_DMA_TXCH_RESET_PCNT(x)	(((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \+						 PAS_IOB_DMA_TXCH_RESET_PCNT_M)+#define    PAS_IOB_DMA_TXCH_RESET_PCNTRST	0x00000020+#define    PAS_IOB_DMA_TXCH_RESET_DCNTRST	0x00000010+#define    PAS_IOB_DMA_TXCH_RESET_TINTC		0x00000008+#define    PAS_IOB_DMA_TXCH_RESET_DINTC		0x00000004+#define    PAS_IOB_DMA_TXCH_RESET_SINTC		0x00000002+#define    PAS_IOB_DMA_TXCH_RESET_PINTC		0x00000001++#define PAS_IOB_DMA_COM_TIMEOUTCFG		0x1700+#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M	0x00ffffff+#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S	0+#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x)	(((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \+						 PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)++/* Transmit descriptor fields */+#define	XCT_MACTX_T		0x8000000000000000ull+#define	XCT_MACTX_ST		0x4000000000000000ull+#define XCT_MACTX_NORES		0x0000000000000000ull+#define XCT_MACTX_8BRES		0x1000000000000000ull+#define XCT_MACTX_24BRES	0x2000000000000000ull+#define XCT_MACTX_40BRES	0x3000000000000000ull+#define XCT_MACTX_I		0x0800000000000000ull+#define XCT_MACTX_O		0x0400000000000000ull+#define XCT_MACTX_E		0x0200000000000000ull+#define XCT_MACTX_VLAN_M	0x0180000000000000ull+#define XCT_MACTX_VLAN_NOP	0x0000000000000000ull+#define XCT_MACTX_VLAN_REMOVE	0x0080000000000000ull+#define XCT_MACTX_VLAN_INSERT   0x0100000000000000ull+#define XCT_MACTX_VLAN_REPLACE  0x0180000000000000ull+#define XCT_MACTX_CRC_M		0x0060000000000000ull+#define XCT_MACTX_CRC_NOP	0x0000000000000000ull+#define XCT_MACTX_CRC_INSERT	0x0020000000000000ull+#define XCT_MACTX_CRC_PAD	0x0040000000000000ull+#define XCT_MACTX_CRC_REPLACE	0x0060000000000000ull+#define XCT_MACTX_SS		0x0010000000000000ull+#define XCT_MACTX_LLEN_M	0x00007fff00000000ull+#define XCT_MACTX_LLEN_S	32ull+#define XCT_MACTX_LLEN(x)	((((long)(x)) << XCT_MACTX_LLEN_S) & \+				 XCT_MACTX_LLEN_M)+#define XCT_MACTX_IPH_M		0x00000000f8000000ull+#define XCT_MACTX_IPH_S		27ull+#define XCT_MACTX_IPH(x)	((((long)(x)) << XCT_MACTX_IPH_S) & \+				 XCT_MACTX_IPH_M)+#define XCT_MACTX_IPO_M		0x0000000007c00000ull+#define XCT_MACTX_IPO_S		22ull+#define XCT_MACTX_IPO(x)	((((long)(x)) << XCT_MACTX_IPO_S) & \+				 XCT_MACTX_IPO_M)+#define XCT_MACTX_CSUM_M	0x0000000000000060ull+#define XCT_MACTX_CSUM_NOP	0x0000000000000000ull+#define XCT_MACTX_CSUM_TCP	0x0000000000000040ull+#define XCT_MACTX_CSUM_UDP	0x0000000000000060ull+#define XCT_MACTX_V6		0x0000000000000010ull+#define XCT_MACTX_C		0x0000000000000004ull+#define XCT_MACTX_AL2		0x0000000000000002ull++#define XCT_PTR_T		0x8000000000000000ull+#define XCT_PTR_LEN_M		0x7ffff00000000000ull+#define XCT_PTR_LEN_S		44+#define XCT_PTR_LEN(x)		((((long)(x)) << XCT_PTR_LEN_S) & \+				 XCT_PTR_LEN_M)+#define XCT_PTR_ADDR_M		0x00000fffffffffffull+#define XCT_PTR_ADDR_S		0+#define XCT_PTR_ADDR(x)		((((long)(x)) << XCT_PTR_ADDR_S) & \+				 XCT_PTR_ADDR_M)++/* Function descriptor fields */+#define	XCT_FUN_T		0x8000000000000000ull+#define	XCT_FUN_ST		0x4000000000000000ull+#define XCT_FUN_NORES		0x0000000000000000ull+#define XCT_FUN_8BRES		0x1000000000000000ull+#define XCT_FUN_24BRES		0x2000000000000000ull+#define XCT_FUN_40BRES		0x3000000000000000ull+#define XCT_FUN_I		0x0800000000000000ull+#define XCT_FUN_O		0x0400000000000000ull+#define XCT_FUN_E		0x0200000000000000ull+#define XCT_FUN_FUN_S		54+#define XCT_FUN_FUN_M		0x01c0000000000000ull+#define XCT_FUN_FUN(num)	((((long)(num)) << XCT_FUN_FUN_S) & \+				XCT_FUN_FUN_M)+#define XCT_FUN_CRM_NOP		0x0000000000000000ull+#define XCT_FUN_CRM_SIG		0x0008000000000000ull+#define XCT_FUN_CRM_ENC		0x0010000000000000ull+#define XCT_FUN_CRM_DEC		0x0018000000000000ull+#define XCT_FUN_CRM_SIG_ENC	0x0020000000000000ull+#define XCT_FUN_CRM_ENC_SIG	0x0028000000000000ull+#define XCT_FUN_CRM_SIG_DEC	0x0030000000000000ull+#define XCT_FUN_CRM_DEC_SIG	0x0038000000000000ull+#define XCT_FUN_LLEN_M		0x0007ffff00000000ull+#define XCT_FUN_LLEN_S		32ULL+#define XCT_FUN_LLEN(x)		((((long)(x)) << XCT_FUN_LLEN_S) & \+				 XCT_FUN_LLEN_M)+#define XCT_FUN_SHL_M		0x00000000f8000000ull+#define XCT_FUN_SHL_S		27ull+#define XCT_FUN_SHL(x)		((((long)(x)) << XCT_FUN_SHL_S) & \+				 XCT_FUN_SHL_M)+#define XCT_FUN_CHL_M		0x0000000007c00000ull+#define XCT_FUN_CHL_S		22ull+#define XCT_FUN_CHL(x)		((((long)(x)) << XCT_FUN_CHL_S) & \+				 XCT_FUN_CHL_M)+#define XCT_FUN_HSZ_M		0x00000000003c0000ull+#define XCT_FUN_HSZ_S		18ull+#define XCT_FUN_HSZ(x)		((((long)(x)) << XCT_FUN_HSZ_S) & \+				 XCT_FUN_HSZ_M)+#define XCT_FUN_ALG_DES		0x0000000000000000ull+#define XCT_FUN_ALG_3DES	0x0000000000008000ull+#define XCT_FUN_ALG_AES		0x0000000000010000ull+#define XCT_FUN_ALG_ARC		0x0000000000018000ull+#define XCT_FUN_ALG_KASUMI	0x0000000000020000ull+#define XCT_FUN_BCM_ECB		0x0000000000000000ull+#define XCT_FUN_BCM_CBC		0x0000000000001000ull+#define XCT_FUN_BCM_CFB		0x0000000000002000ull+#define XCT_FUN_BCM_OFB		0x0000000000003000ull+#define XCT_FUN_BCM_CNT		0x0000000000003800ull+#define XCT_FUN_BCM_KAS_F8	0x0000000000002800ull+#define XCT_FUN_BCM_KAS_F9	0x0000000000001800ull+#define XCT_FUN_BCP_NO_PAD	0x0000000000000000ull+#define XCT_FUN_BCP_ZRO		0x0000000000000200ull+#define XCT_FUN_BCP_PL		0x0000000000000400ull+#define XCT_FUN_BCP_INCR	0x0000000000000600ull+#define XCT_FUN_SIG_MD5		(0ull << 4)+#define XCT_FUN_SIG_SHA1	(2ull << 4)+#define XCT_FUN_SIG_HMAC_MD5	(8ull << 4)+#define XCT_FUN_SIG_HMAC_SHA1	(10ull << 4)+#define XCT_FUN_A		0x0000000000000008ull+#define XCT_FUN_C		0x0000000000000004ull+#define XCT_FUN_AL2		0x0000000000000002ull+#define XCT_FUN_SE		0x0000000000000001ull++#define XCT_FUN_SRC_PTR(len, addr)	(XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))+#define XCT_FUN_DST_PTR(len, addr)	(XCT_FUN_SRC_PTR(len, addr) | \+					0x8000000000000000ull)++#define XCT_CTRL_HDR_FUN_NUM_M		0x01c0000000000000ull+#define XCT_CTRL_HDR_FUN_NUM_S		54+#define XCT_CTRL_HDR_LEN_M		0x0007ffff00000000ull+#define XCT_CTRL_HDR_LEN_S		32+#define XCT_CTRL_HDR_REG_M		0x00000000000000ffull+#define XCT_CTRL_HDR_REG_S		0++#define XCT_CTRL_HDR(funcN,len,reg)	(0x9400000000000000ull | \+			((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \+			& XCT_CTRL_HDR_FUN_NUM_M) | \+			((((long)(len)) << \+			XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \+			((((long)(reg)) << \+			XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))++/* Function config command options */+#define	DMA_CALGO_DES			0x00+#define	DMA_CALGO_3DES			0x01+#define	DMA_CALGO_AES			0x02+#define	DMA_CALGO_ARC			0x03++#define DMA_FN_CIV0			0x02+#define DMA_FN_CIV1			0x03+#define DMA_FN_HKEY0			0x0a++#define XCT_PTR_ADDR_LEN(ptr)		((ptr) & XCT_PTR_ADDR_M), \+			(((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)++#endif /* PASEMI_FNU_H */diff -Nur linux-2.6.36.orig/crypto/ocf/random.c linux-2.6.36/crypto/ocf/random.c--- linux-2.6.36.orig/crypto/ocf/random.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/random.c	2010-11-09 20:28:12.652495434 +0100@@ -0,0 +1,322 @@+/*+ * A system independant way of adding entropy to the kernels pool+ * this way the drivers can focus on the real work and we can take+ * care of pushing it to the appropriate place in the kernel.+ *+ * This should be fast and callable from timers/interrupts+ *+ * Written by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this product+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/wait.h>+#include <linux/sched.h>+#include <linux/spinlock.h>+#include <linux/version.h>+#include <linux/unistd.h>+#include <linux/poll.h>+#include <linux/random.h>+#include <cryptodev.h>++#ifdef CONFIG_OCF_FIPS+#include "rndtest.h"+#endif++#ifndef HAS_RANDOM_INPUT_WAIT+#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"+#endif++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)+#include <linux/sched.h>+#define	kill_proc(p,s,v)	send_sig(s,find_task_by_vpid(p),0)+#endif++/*+ * a hack to access the debug levels from the crypto driver+ */+extern int crypto_debug;+#define debug crypto_debug++/*+ * a list of all registered random providers+ */+static LIST_HEAD(random_ops);+static int started = 0;+static int initted = 0;++struct random_op {+	struct list_head random_list;+	u_int32_t driverid;+	int (*read_random)(void *arg, u_int32_t *buf, int len);+	void *arg;+};++static int random_proc(void *arg);++static pid_t		randomproc = (pid_t) -1;+static spinlock_t	random_lock;++/*+ * just init the spin locks+ */+static int+crypto_random_init(void)+{+	spin_lock_init(&random_lock);+	initted = 1;+	return(0);+}++/*+ * Add the given random reader to our list (if not present)+ * and start the thread (if not already started)+ *+ * we have to assume that driver id is ok for now+ */+int+crypto_rregister(+	u_int32_t driverid,+	int (*read_random)(void *arg, u_int32_t *buf, int len),+	void *arg)+{+	unsigned long flags;+	int ret = 0;+	struct random_op	*rops, *tmp;++	dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,+			__FUNCTION__, driverid, read_random, arg);++	if (!initted)+		crypto_random_init();++#if 0+	struct cryptocap	*cap;++	cap = crypto_checkdriver(driverid);+	if (!cap)+		return EINVAL;+#endif++	list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {+		if (rops->driverid == driverid && rops->read_random == read_random)+			return EEXIST;+	}++	rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);+	if (!rops)+		return ENOMEM;++	rops->driverid    = driverid;+	rops->read_random = read_random;+	rops->arg = arg;++	spin_lock_irqsave(&random_lock, flags);+	list_add_tail(&rops->random_list, &random_ops);+	if (!started) {+		randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);+		if (randomproc < 0) {+			ret = randomproc;+			printk("crypto: crypto_rregister cannot start random thread; "+					"error %d", ret);+		} else+			started = 1;+	}+	spin_unlock_irqrestore(&random_lock, flags);++	return ret;+}+EXPORT_SYMBOL(crypto_rregister);++int+crypto_runregister_all(u_int32_t driverid)+{+	struct random_op *rops, *tmp;+	unsigned long flags;++	dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);++	list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {+		if (rops->driverid == driverid) {+			list_del(&rops->random_list);+			kfree(rops);+		}+	}++	spin_lock_irqsave(&random_lock, flags);+	if (list_empty(&random_ops) && started)+		kill_proc(randomproc, SIGKILL, 1);+	spin_unlock_irqrestore(&random_lock, flags);+	return(0);+}+EXPORT_SYMBOL(crypto_runregister_all);++/*+ * while we can add entropy to random.c continue to read random data from+ * the drivers and push it to random.+ */+static int+random_proc(void *arg)+{+	int n;+	int wantcnt;+	int bufcnt = 0;+	int retval = 0;+	int *buf = NULL;++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+	daemonize();+	spin_lock_irq(¤t->sigmask_lock);+	sigemptyset(¤t->blocked);+	recalc_sigpending(current);+	spin_unlock_irq(¤t->sigmask_lock);+	sprintf(current->comm, "ocf-random");+#else+	daemonize("ocf-random");+	allow_signal(SIGKILL);+#endif++	(void) get_fs();+	set_fs(get_ds());++#ifdef CONFIG_OCF_FIPS+#define NUM_INT (RNDTEST_NBYTES/sizeof(int))+#else+#define NUM_INT 32+#endif++	/*+	 * some devices can transferr their RNG data direct into memory,+	 * so make sure it is device friendly+	 */+	buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);+	if (NULL == buf) {+		printk("crypto: RNG could not allocate memory\n");+		retval = -ENOMEM;+		goto bad_alloc;+	}++	wantcnt = NUM_INT;   /* start by adding some entropy */++	/*+	 * its possible due to errors or driver removal that we no longer+	 * have anything to do,  if so exit or we will consume all the CPU+	 * doing nothing+	 */+	while (!list_empty(&random_ops)) {+		struct random_op	*rops, *tmp;++#ifdef CONFIG_OCF_FIPS+		if (wantcnt)+			wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */+#endif++		/* see if we can get enough entropy to make the world+		 * a better place.+		 */+		while (bufcnt < wantcnt && bufcnt < NUM_INT) {+			list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {++				n = (*rops->read_random)(rops->arg, &buf[bufcnt],+							 NUM_INT - bufcnt);++				/* on failure remove the random number generator */+				if (n == -1) {+					list_del(&rops->random_list);+					printk("crypto: RNG (driverid=0x%x) failed, disabling\n",+							rops->driverid);+					kfree(rops);+				} else if (n > 0)+					bufcnt += n;+			}+			/* give up CPU for a bit, just in case as this is a loop */+			schedule();+		}+++#ifdef CONFIG_OCF_FIPS+		if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {+			dprintk("crypto: buffer had fips errors, discarding\n");+			bufcnt = 0;+		}+#endif++		/*+		 * if we have a certified buffer,  we can send some data+		 * to /dev/random and move along+		 */+		if (bufcnt > 0) {+			/* add what we have */+			random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);+			bufcnt = 0;+		}++		/* give up CPU for a bit so we don't hog while filling */+		schedule();++		/* wait for needing more */+		wantcnt = random_input_wait();++		if (wantcnt <= 0)+			wantcnt = 0; /* try to get some info again */+		else+		 	/* round up to one word or we can loop forever */+			wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);+		if (wantcnt > NUM_INT) {+			wantcnt = NUM_INT;+		}++		if (signal_pending(current)) {+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+			spin_lock_irq(¤t->sigmask_lock);+#endif+			flush_signals(current);+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+			spin_unlock_irq(¤t->sigmask_lock);+#endif+		}+	}+	+	kfree(buf);++bad_alloc:+	spin_lock_irq(&random_lock);+	randomproc = (pid_t) -1;+	started = 0;+	spin_unlock_irq(&random_lock);++	return retval;+}+diff -Nur linux-2.6.36.orig/crypto/ocf/README linux-2.6.36/crypto/ocf/README--- linux-2.6.36.orig/crypto/ocf/README	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/README	2010-11-09 20:28:12.681240186 +0100@@ -0,0 +1,167 @@+README - ocf-linux-20100325+---------------------------++This README provides instructions for getting ocf-linux compiled and+operating in a generic linux environment.  For other information you+might like to visit the home page for this project:++    http://ocf-linux.sourceforge.net/++Adding OCF to linux+-------------------++    Not much in this file for now,  just some notes.  I usually build+    the ocf support as modules but it can be built into the kernel as+    well.  To use it:++    * mknod /dev/crypto c 10 70++    * to add OCF to your kernel source,  you have two options.  Apply+      the kernel specific patch:++          cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1+          cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1+    +      if you do one of the above,  then you can proceed to the next step,+      or you can do the above process by hand with using the patches against+      linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.+      Here's how to add it:++      for 2.4.35 (and later)++          cd linux-2.4.35/crypto+          tar xvzf ocf-linux.tar.gz+          cd ..+          patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch++      for 2.6.23 (and later),  find the kernel patch specific (or nearest)+      to your kernel versions and then:++          cd linux-2.6.NN/crypto+          tar xvzf ocf-linux.tar.gz+          cd ..+          patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch++      It should be easy to take this patch and apply it to other more+      recent versions of the kernels.  The same patches should also work+      relatively easily on kernels as old as 2.6.11 and 2.4.18.+      +    * under 2.4 if you are on a non-x86 platform,  you may need to:++        cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY++      so that you can build the kernel crypto support needed for the cryptosoft+      driver.++    * For simplicity you should enable all the crypto support in your kernel+      except for the test driver.  Likewise for the OCF options.  Do not+      enable OCF crypto drivers for HW that you do not have (for example+      ixp4xx will not compile on non-Xscale systems).++    * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as+      crypto/cryptodev.h in an include directory that is used for building+      applications for your platform.  For example on a host system that+      might be:++              /usr/include/crypto/cryptodev.h++    * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.+      (NOTE: there is no longer a need to patch ssh). The patch is against:+      openssl-0_9_8e++      If you need a patch for an older version of openssl,  you should look+      to older OCF releases.  This patch is unlikely to work on older+      openssl versions.++      openssl-0.9.8n.patch+                - enables --with-cryptodev for non BSD systems+                - adds -cpu option to openssl speed for calculating CPU load+                  under linux+                - fixes null pointer in openssl speed multi thread output.+                - fixes test keys to work with linux crypto's more stringent+                  key checking.+                - adds MD5/SHA acceleration (Ronen Shitrit), only enabled+                  with the --with-cryptodev-digests option+                - fixes bug in engine code caching.++    * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD+      tools for testing OCF (ie., cryptotest).++How to load the OCF drivers+---------------------------++    First insert the base modules:++        insmod ocf+        insmod cryptodev++    You can then install the software OCF driver with:++        insmod cryptosoft++    and one or more of the OCF HW drivers with:++        insmod safe+        insmod hifn7751+        insmod ixp4xx+        ...++    all the drivers take a debug option to enable verbose debug so that+    you can see what is going on.  For debug you load them as:++        insmod ocf crypto_debug=1+        insmod cryptodev cryptodev_debug=1+        insmod cryptosoft swcr_debug=1++    You may load more than one OCF crypto driver but then there is no guarantee+    as to which will be used.++    You can also enable debug at run time on 2.6 systems with the following:++        echo 1 > /sys/module/ocf/parameters/crypto_debug+        echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug+        echo 1 > /sys/module/cryptosoft/parameters/swcr_debug+        echo 1 > /sys/module/hifn7751/parameters/hifn_debug+        echo 1 > /sys/module/safe/parameters/safe_debug+        echo 1 > /sys/module/ixp4xx/parameters/ixp_debug+        ...++Testing the OCF support+-----------------------++    run "cryptotest",  it should do a short test for a couple of+    des packets.  If it does everything is working.++    If this works,  then ssh will use the driver when invoked as:++        ssh -c 3des username@host++    to see for sure that it is operating, enable debug as defined above.++    To get a better idea of performance run:++        cryptotest 100 4096++    There are more options to cryptotest,  see the help.++    It is also possible to use openssl to test the speed of the crypto+    drivers.++        openssl speed -evp des -engine cryptodev -elapsed+        openssl speed -evp des3 -engine cryptodev -elapsed+        openssl speed -evp aes128 -engine cryptodev -elapsed++    and multiple threads (10) with:++        openssl speed -evp des -engine cryptodev -elapsed -multi 10+        openssl speed -evp des3 -engine cryptodev -elapsed -multi 10+        openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10++    for public key testing you can try:++        cryptokeytest+        openssl speed -engine cryptodev rsa -elapsed+        openssl speed -engine cryptodev dsa -elapsed++David McCullough+david_mccullough@mcafee.comdiff -Nur linux-2.6.36.orig/crypto/ocf/rndtest.c linux-2.6.36/crypto/ocf/rndtest.c--- linux-2.6.36.orig/crypto/ocf/rndtest.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/rndtest.c	2010-11-09 20:28:12.722495563 +0100@@ -0,0 +1,300 @@+/*	$OpenBSD$	*/++/*+ * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ * The license and original author are listed below.+ *+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. All advertising materials mentioning features or use of this software+ *    must display the following acknowledgement:+ *	This product includes software developed by Jason L. Wright+ * 4. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+ * POSSIBILITY OF SUCH DAMAGE.+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/list.h>+#include <linux/wait.h>+#include <linux/time.h>+#include <linux/version.h>+#include <linux/unistd.h>+#include <linux/kernel.h>+#include <linux/string.h>+#include <linux/time.h>+#include <cryptodev.h>+#include "rndtest.h"++static struct rndtest_stats rndstats;++static	void rndtest_test(struct rndtest_state *);++/* The tests themselves */+static	int rndtest_monobit(struct rndtest_state *);+static	int rndtest_runs(struct rndtest_state *);+static	int rndtest_longruns(struct rndtest_state *);+static	int rndtest_chi_4(struct rndtest_state *);++static	int rndtest_runs_check(struct rndtest_state *, int, int *);+static	void rndtest_runs_record(struct rndtest_state *, int, int *);++static const struct rndtest_testfunc {+	int (*test)(struct rndtest_state *);+} rndtest_funcs[] = {+	{ rndtest_monobit },+	{ rndtest_runs },+	{ rndtest_chi_4 },+	{ rndtest_longruns },+};++#define	RNDTEST_NTESTS	(sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))++static void+rndtest_test(struct rndtest_state *rsp)+{+	int i, rv = 0;++	rndstats.rst_tests++;+	for (i = 0; i < RNDTEST_NTESTS; i++)+		rv |= (*rndtest_funcs[i].test)(rsp);+	rsp->rs_discard = (rv != 0);+}+++extern int crypto_debug;+#define rndtest_verbose 2+#define rndtest_report(rsp, failure, fmt, a...) \+	{ if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }++#define	RNDTEST_MONOBIT_MINONES	9725+#define	RNDTEST_MONOBIT_MAXONES	10275++static int+rndtest_monobit(struct rndtest_state *rsp)+{+	int i, ones = 0, j;+	u_int8_t r;++	for (i = 0; i < RNDTEST_NBYTES; i++) {+		r = rsp->rs_buf[i];+		for (j = 0; j < 8; j++, r <<= 1)+			if (r & 0x80)+				ones++;+	}+	if (ones > RNDTEST_MONOBIT_MINONES &&+	    ones < RNDTEST_MONOBIT_MAXONES) {+		if (rndtest_verbose > 1)+			rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",+			    RNDTEST_MONOBIT_MINONES, ones,+			    RNDTEST_MONOBIT_MAXONES);+		return (0);+	} else {+		if (rndtest_verbose)+			rndtest_report(rsp, 1,+			    "monobit failed (%d ones)", ones);+		rndstats.rst_monobit++;+		return (-1);+	}+}++#define	RNDTEST_RUNS_NINTERVAL	6++static const struct rndtest_runs_tabs {+	u_int16_t min, max;+} rndtest_runs_tab[] = {+	{ 2343, 2657 },+	{ 1135, 1365 },+	{ 542, 708 },+	{ 251, 373 },+	{ 111, 201 },+	{ 111, 201 },+};++static int+rndtest_runs(struct rndtest_state *rsp)+{+	int i, j, ones, zeros, rv = 0;+	int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];+	u_int8_t c;++	bzero(onei, sizeof(onei));+	bzero(zeroi, sizeof(zeroi));+	ones = zeros = 0;+	for (i = 0; i < RNDTEST_NBYTES; i++) {+		c = rsp->rs_buf[i];+		for (j = 0; j < 8; j++, c <<= 1) {+			if (c & 0x80) {+				ones++;+				rndtest_runs_record(rsp, zeros, zeroi);+				zeros = 0;+			} else {+				zeros++;+				rndtest_runs_record(rsp, ones, onei);+				ones = 0;+			}+		}+	}+	rndtest_runs_record(rsp, ones, onei);+	rndtest_runs_record(rsp, zeros, zeroi);++	rv |= rndtest_runs_check(rsp, 0, zeroi);+	rv |= rndtest_runs_check(rsp, 1, onei);++	if (rv)+		rndstats.rst_runs++;++	return (rv);+}++static void+rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)+{+	if (len == 0)+		return;+	if (len > RNDTEST_RUNS_NINTERVAL)+		len = RNDTEST_RUNS_NINTERVAL;+	len -= 1;+	intrv[len]++;+}++static int+rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)+{+	int i, rv = 0;++	for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {+		if (src[i] < rndtest_runs_tab[i].min ||+		    src[i] > rndtest_runs_tab[i].max) {+			rndtest_report(rsp, 1,+			    "%s interval %d failed (%d, %d-%d)",+			    val ? "ones" : "zeros",+			    i + 1, src[i], rndtest_runs_tab[i].min,+			    rndtest_runs_tab[i].max);+			rv = -1;+		} else {+			rndtest_report(rsp, 0,+			    "runs pass %s interval %d (%d < %d < %d)",+			    val ? "ones" : "zeros",+			    i + 1, rndtest_runs_tab[i].min, src[i],+			    rndtest_runs_tab[i].max);+		}+	}+	return (rv);+}++static int+rndtest_longruns(struct rndtest_state *rsp)+{+	int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;+	u_int8_t c;++	for (i = 0; i < RNDTEST_NBYTES; i++) {+		c = rsp->rs_buf[i];+		for (j = 0; j < 8; j++, c <<= 1) {+			if (c & 0x80) {+				zeros = 0;+				ones++;+				if (ones > maxones)+					maxones = ones;+			} else {+				ones = 0;+				zeros++;+				if (zeros > maxzeros)+					maxzeros = zeros;+			}+		}+	}++	if (maxones < 26 && maxzeros < 26) {+		rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",+			maxones, maxzeros);+		return (0);+	} else {+		rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",+			maxones, maxzeros);+		rndstats.rst_longruns++;+		return (-1);+	}+}++/*+ * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,+ * but it is really the chi^2 test over 4 bits (the poker test as described+ * by Knuth vol 2 is something different, and I take him as authoritative+ * on nomenclature over NIST).+ */+#define	RNDTEST_CHI4_K	16+#define	RNDTEST_CHI4_K_MASK	(RNDTEST_CHI4_K - 1)++/*+ * The unnormalized values are used so that we don't have to worry about+ * fractional precision.  The "real" value is found by:+ *	(V - 1562500) * (16 / 5000) = Vn   (where V is the unnormalized value)+ */+#define	RNDTEST_CHI4_VMIN	1563181		/* 2.1792 */+#define	RNDTEST_CHI4_VMAX	1576929		/* 46.1728 */++static int+rndtest_chi_4(struct rndtest_state *rsp)+{+	unsigned int freq[RNDTEST_CHI4_K], i, sum;++	for (i = 0; i < RNDTEST_CHI4_K; i++)+		freq[i] = 0;++	/* Get number of occurances of each 4 bit pattern */+	for (i = 0; i < RNDTEST_NBYTES; i++) {+		freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;+		freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;+	}++	for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)+		sum += freq[i] * freq[i];++	if (sum >= 1563181 && sum <= 1576929) {+		rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);+		return (0);+	} else {+		rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);+		rndstats.rst_chi++;+		return (-1);+	}+}++int+rndtest_buf(unsigned char *buf)+{+	struct rndtest_state rsp;++	memset(&rsp, 0, sizeof(rsp));+	rsp.rs_buf = buf;+	rndtest_test(&rsp);+	return(rsp.rs_discard);+}+diff -Nur linux-2.6.36.orig/crypto/ocf/rndtest.h linux-2.6.36/crypto/ocf/rndtest.h--- linux-2.6.36.orig/crypto/ocf/rndtest.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/rndtest.h	2010-11-09 20:28:12.762495556 +0100@@ -0,0 +1,54 @@+/*	$FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $	*/+/*	$OpenBSD$	*/++/*+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. All advertising materials mentioning features or use of this software+ *    must display the following acknowledgement:+ *	This product includes software developed by Jason L. Wright+ * 4. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+ * POSSIBILITY OF SUCH DAMAGE.+ */+++/* Some of the tests depend on these values */+#define	RNDTEST_NBYTES	2500+#define	RNDTEST_NBITS	(8 * RNDTEST_NBYTES)++struct rndtest_state {+	int		rs_discard;	/* discard/accept random data */+	u_int8_t	*rs_buf;+};++struct rndtest_stats {+	u_int32_t	rst_discard;	/* number of bytes discarded */+	u_int32_t	rst_tests;	/* number of test runs */+	u_int32_t	rst_monobit;	/* monobit test failures */+	u_int32_t	rst_runs;	/* 0/1 runs failures */+	u_int32_t	rst_longruns;	/* longruns failures */+	u_int32_t	rst_chi;	/* chi^2 failures */+};++extern int rndtest_buf(unsigned char *buf);diff -Nur linux-2.6.36.orig/crypto/ocf/safe/Makefile linux-2.6.36/crypto/ocf/safe/Makefile--- linux-2.6.36.orig/crypto/ocf/safe/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/Makefile	2010-11-09 20:28:12.805576889 +0100@@ -0,0 +1,12 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_SAFE) += safe.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/safe/md5.c linux-2.6.36/crypto/ocf/safe/md5.c--- linux-2.6.36.orig/crypto/ocf/safe/md5.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/md5.c	2010-11-09 20:28:12.842495449 +0100@@ -0,0 +1,308 @@+/*	$KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $	*/+/*+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the project nor the names of its contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#if 0+#include <sys/cdefs.h>+__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");++#include <sys/types.h>+#include <sys/cdefs.h>+#include <sys/time.h>+#include <sys/systm.h>+#include <crypto/md5.h>+#endif++#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))++#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))+#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))+#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))+#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))++#define ROUND1(a, b, c, d, k, s, i) { \+	(a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \+	(a) = SHIFT((a), (s)); \+	(a) = (b) + (a); \+}++#define ROUND2(a, b, c, d, k, s, i) { \+	(a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \+	(a) = SHIFT((a), (s)); \+	(a) = (b) + (a); \+}++#define ROUND3(a, b, c, d, k, s, i) { \+	(a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \+	(a) = SHIFT((a), (s)); \+	(a) = (b) + (a); \+}++#define ROUND4(a, b, c, d, k, s, i) { \+	(a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \+	(a) = SHIFT((a), (s)); \+	(a) = (b) + (a); \+}++#define Sa	 7+#define Sb	12+#define Sc	17+#define Sd	22++#define Se	 5+#define Sf	 9+#define Sg	14+#define Sh	20++#define Si	 4+#define Sj	11+#define Sk	16+#define Sl	23++#define Sm	 6+#define Sn	10+#define So	15+#define Sp	21++#define MD5_A0	0x67452301+#define MD5_B0	0xefcdab89+#define MD5_C0	0x98badcfe+#define MD5_D0	0x10325476++/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */+static const u_int32_t T[65] = {+	0,+	0xd76aa478, 	0xe8c7b756,	0x242070db,	0xc1bdceee,+	0xf57c0faf,	0x4787c62a, 	0xa8304613,	0xfd469501,+	0x698098d8,	0x8b44f7af,	0xffff5bb1,	0x895cd7be,+	0x6b901122, 	0xfd987193, 	0xa679438e,	0x49b40821,++	0xf61e2562,	0xc040b340, 	0x265e5a51, 	0xe9b6c7aa,+	0xd62f105d,	0x2441453,	0xd8a1e681,	0xe7d3fbc8,+	0x21e1cde6,	0xc33707d6, 	0xf4d50d87, 	0x455a14ed,+	0xa9e3e905,	0xfcefa3f8, 	0x676f02d9, 	0x8d2a4c8a,++	0xfffa3942,	0x8771f681, 	0x6d9d6122, 	0xfde5380c,+	0xa4beea44, 	0x4bdecfa9, 	0xf6bb4b60, 	0xbebfbc70,+	0x289b7ec6, 	0xeaa127fa, 	0xd4ef3085,	0x4881d05,+	0xd9d4d039, 	0xe6db99e5, 	0x1fa27cf8, 	0xc4ac5665,++	0xf4292244, 	0x432aff97, 	0xab9423a7, 	0xfc93a039,+	0x655b59c3, 	0x8f0ccc92, 	0xffeff47d, 	0x85845dd1,+	0x6fa87e4f, 	0xfe2ce6e0, 	0xa3014314, 	0x4e0811a1,+	0xf7537e82, 	0xbd3af235, 	0x2ad7d2bb, 	0xeb86d391,+};++static const u_int8_t md5_paddat[MD5_BUFLEN] = {+	0x80,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,+	0,	0,	0,	0,	0,	0,	0,	0,	+};++static void md5_calc(u_int8_t *, md5_ctxt *);++void md5_init(ctxt)+	md5_ctxt *ctxt;+{+	ctxt->md5_n = 0;+	ctxt->md5_i = 0;+	ctxt->md5_sta = MD5_A0;+	ctxt->md5_stb = MD5_B0;+	ctxt->md5_stc = MD5_C0;+	ctxt->md5_std = MD5_D0;+	bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));+}++void md5_loop(ctxt, input, len)+	md5_ctxt *ctxt;+	u_int8_t *input;+	u_int len; /* number of bytes */+{+	u_int gap, i;++	ctxt->md5_n += len * 8; /* byte to bit */+	gap = MD5_BUFLEN - ctxt->md5_i;++	if (len >= gap) {+		bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),+			gap);+		md5_calc(ctxt->md5_buf, ctxt);++		for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {+			md5_calc((u_int8_t *)(input + i), ctxt);+		}+		+		ctxt->md5_i = len - i;+		bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);+	} else {+		bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),+			len);+		ctxt->md5_i += len;+	}+}++void md5_pad(ctxt)+	md5_ctxt *ctxt;+{+	u_int gap;++	/* Don't count up padding. Keep md5_n. */	+	gap = MD5_BUFLEN - ctxt->md5_i;+	if (gap > 8) {+		bcopy(md5_paddat,+		      (void *)(ctxt->md5_buf + ctxt->md5_i),+		      gap - sizeof(ctxt->md5_n));+	} else {+		/* including gap == 8 */+		bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),+			gap);+		md5_calc(ctxt->md5_buf, ctxt);+		bcopy((md5_paddat + gap),+		      (void *)ctxt->md5_buf,+		      MD5_BUFLEN - sizeof(ctxt->md5_n));+	}++	/* 8 byte word */	+#if BYTE_ORDER == LITTLE_ENDIAN+	bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);+#endif+#if BYTE_ORDER == BIG_ENDIAN+	ctxt->md5_buf[56] = ctxt->md5_n8[7];+	ctxt->md5_buf[57] = ctxt->md5_n8[6];+	ctxt->md5_buf[58] = ctxt->md5_n8[5];+	ctxt->md5_buf[59] = ctxt->md5_n8[4];+	ctxt->md5_buf[60] = ctxt->md5_n8[3];+	ctxt->md5_buf[61] = ctxt->md5_n8[2];+	ctxt->md5_buf[62] = ctxt->md5_n8[1];+	ctxt->md5_buf[63] = ctxt->md5_n8[0];+#endif++	md5_calc(ctxt->md5_buf, ctxt);+}++void md5_result(digest, ctxt)+	u_int8_t *digest;+	md5_ctxt *ctxt;+{+	/* 4 byte words */+#if BYTE_ORDER == LITTLE_ENDIAN+	bcopy(&ctxt->md5_st8[0], digest, 16);+#endif+#if BYTE_ORDER == BIG_ENDIAN+	digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];+	digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];+	digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];+	digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];+	digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];+	digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];+	digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];+	digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];+#endif+}++static void md5_calc(b64, ctxt)+	u_int8_t *b64;+	md5_ctxt *ctxt;+{+	u_int32_t A = ctxt->md5_sta;+	u_int32_t B = ctxt->md5_stb;+	u_int32_t C = ctxt->md5_stc;+	u_int32_t D = ctxt->md5_std;+#if BYTE_ORDER == LITTLE_ENDIAN+	u_int32_t *X = (u_int32_t *)b64;+#endif	+#if BYTE_ORDER == BIG_ENDIAN+	/* 4 byte words */+	/* what a brute force but fast! */+	u_int32_t X[16];+	u_int8_t *y = (u_int8_t *)X;+	y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];+	y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];+	y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];+	y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];+	y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];+	y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];+	y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];+	y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];+	y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];+	y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];+	y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];+	y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];+	y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];+	y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];+	y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];+	y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];+#endif++	ROUND1(A, B, C, D,  0, Sa,  1); ROUND1(D, A, B, C,  1, Sb,  2);+	ROUND1(C, D, A, B,  2, Sc,  3); ROUND1(B, C, D, A,  3, Sd,  4);+	ROUND1(A, B, C, D,  4, Sa,  5); ROUND1(D, A, B, C,  5, Sb,  6);+	ROUND1(C, D, A, B,  6, Sc,  7); ROUND1(B, C, D, A,  7, Sd,  8);+	ROUND1(A, B, C, D,  8, Sa,  9); ROUND1(D, A, B, C,  9, Sb, 10);+	ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);+	ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);+	ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);+	+	ROUND2(A, B, C, D,  1, Se, 17); ROUND2(D, A, B, C,  6, Sf, 18);+	ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A,  0, Sh, 20);+	ROUND2(A, B, C, D,  5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);+	ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A,  4, Sh, 24);+	ROUND2(A, B, C, D,  9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);+	ROUND2(C, D, A, B,  3, Sg, 27); ROUND2(B, C, D, A,  8, Sh, 28);+	ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C,  2, Sf, 30);+	ROUND2(C, D, A, B,  7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);++	ROUND3(A, B, C, D,  5, Si, 33); ROUND3(D, A, B, C,  8, Sj, 34);+	ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);+	ROUND3(A, B, C, D,  1, Si, 37); ROUND3(D, A, B, C,  4, Sj, 38);+	ROUND3(C, D, A, B,  7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);+	ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C,  0, Sj, 42);+	ROUND3(C, D, A, B,  3, Sk, 43); ROUND3(B, C, D, A,  6, Sl, 44);+	ROUND3(A, B, C, D,  9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);+	ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A,  2, Sl, 48);+	+	ROUND4(A, B, C, D,  0, Sm, 49); ROUND4(D, A, B, C,  7, Sn, 50);	+	ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A,  5, Sp, 52);	+	ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C,  3, Sn, 54);	+	ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A,  1, Sp, 56);	+	ROUND4(A, B, C, D,  8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);	+	ROUND4(C, D, A, B,  6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);	+	ROUND4(A, B, C, D,  4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);	+	ROUND4(C, D, A, B,  2, So, 63); ROUND4(B, C, D, A,  9, Sp, 64);++	ctxt->md5_sta += A;+	ctxt->md5_stb += B;+	ctxt->md5_stc += C;+	ctxt->md5_std += D;+}diff -Nur linux-2.6.36.orig/crypto/ocf/safe/md5.h linux-2.6.36/crypto/ocf/safe/md5.h--- linux-2.6.36.orig/crypto/ocf/safe/md5.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/md5.h	2010-11-09 20:28:12.881683669 +0100@@ -0,0 +1,76 @@+/*	$FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $	*/+/*	$KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $	*/++/*+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the project nor the names of its contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#ifndef _NETINET6_MD5_H_+#define _NETINET6_MD5_H_++#define MD5_BUFLEN	64++typedef struct {+	union {+		u_int32_t	md5_state32[4];+		u_int8_t	md5_state8[16];+	} md5_st;++#define md5_sta		md5_st.md5_state32[0]+#define md5_stb		md5_st.md5_state32[1]+#define md5_stc		md5_st.md5_state32[2]+#define md5_std		md5_st.md5_state32[3]+#define md5_st8		md5_st.md5_state8++	union {+		u_int64_t	md5_count64;+		u_int8_t	md5_count8[8];+	} md5_count;+#define md5_n	md5_count.md5_count64+#define md5_n8	md5_count.md5_count8++	u_int	md5_i;+	u_int8_t	md5_buf[MD5_BUFLEN];+} md5_ctxt;++extern void md5_init(md5_ctxt *);+extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);+extern void md5_pad(md5_ctxt *);+extern void md5_result(u_int8_t *, md5_ctxt *);++/* compatibility */+#define MD5_CTX		md5_ctxt+#define MD5Init(x)	md5_init((x))+#define MD5Update(x, y, z)	md5_loop((x), (y), (z))+#define MD5Final(x, y) \+do {				\+	md5_pad((y));		\+	md5_result((x), (y));	\+} while (0)++#endif /* ! _NETINET6_MD5_H_*/diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safe.c linux-2.6.36/crypto/ocf/safe/safe.c--- linux-2.6.36.orig/crypto/ocf/safe/safe.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/safe.c	2010-11-09 20:28:12.922204086 +0100@@ -0,0 +1,2288 @@+/*-+ * Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2004-2010 David McCullough+ * The license and original author are listed below.+ *+ * Copyright (c) 2003 Sam Leffler, Errno Consulting+ * Copyright (c) 2003 Global Technology Associates, Inc.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ *+__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/kernel.h>+#include <linux/init.h>+#include <linux/list.h>+#include <linux/slab.h>+#include <linux/wait.h>+#include <linux/sched.h>+#include <linux/pci.h>+#include <linux/delay.h>+#include <linux/interrupt.h>+#include <linux/spinlock.h>+#include <linux/random.h>+#include <linux/version.h>+#include <linux/skbuff.h>+#include <asm/io.h>++/*+ * SafeNet SafeXcel-1141 hardware crypto accelerator+ */++#include <cryptodev.h>+#include <uio.h>+#include <safe/safereg.h>+#include <safe/safevar.h>++#if 1+#define	DPRINTF(a)	do { \+						if (debug) { \+							printk("%s: ", sc ? \+								device_get_nameunit(sc->sc_dev) : "safe"); \+							printk a; \+						} \+					} while (0)+#else+#define	DPRINTF(a)+#endif++/*+ * until we find a cleaner way, include the BSD md5/sha1 code+ * here+ */+#define HMAC_HACK 1+#ifdef HMAC_HACK+#define LITTLE_ENDIAN 1234+#define BIG_ENDIAN 4321+#ifdef __LITTLE_ENDIAN+#define BYTE_ORDER LITTLE_ENDIAN+#endif+#ifdef __BIG_ENDIAN+#define BYTE_ORDER BIG_ENDIAN+#endif+#include <safe/md5.h>+#include <safe/md5.c>+#include <safe/sha1.h>+#include <safe/sha1.c>++u_int8_t hmac_ipad_buffer[64] = {+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36+};++u_int8_t hmac_opad_buffer[64] = {+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,+    0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C+};+#endif /* HMAC_HACK */++/* add proc entry for this */+struct safe_stats safestats;++#define debug safe_debug+int safe_debug = 0;+module_param(safe_debug, int, 0644);+MODULE_PARM_DESC(safe_debug, "Enable debug");++static	void safe_callback(struct safe_softc *, struct safe_ringentry *);+static	void safe_feed(struct safe_softc *, struct safe_ringentry *);+#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)+static	void safe_rng_init(struct safe_softc *);+int safe_rngbufsize = 8;		/* 32 bytes each read  */+module_param(safe_rngbufsize, int, 0644);+MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");+int safe_rngmaxalarm = 8;		/* max alarms before reset */+module_param(safe_rngmaxalarm, int, 0644);+MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");+#endif /* SAFE_NO_RNG */++static void safe_totalreset(struct safe_softc *sc);+static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);+static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);+static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);+static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);+static int safe_kstart(struct safe_softc *sc);+static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);+static void safe_kfeed(struct safe_softc *sc);+static void safe_kpoll(unsigned long arg);+static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,+								u_int32_t len, struct crparam *n);++static	int safe_newsession(device_t, u_int32_t *, struct cryptoini *);+static	int safe_freesession(device_t, u_int64_t);+static	int safe_process(device_t, struct cryptop *, int);++static device_method_t safe_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	safe_newsession),+	DEVMETHOD(cryptodev_freesession,safe_freesession),+	DEVMETHOD(cryptodev_process,	safe_process),+	DEVMETHOD(cryptodev_kprocess,	safe_kprocess),+};++#define	READ_REG(sc,r)			readl((sc)->sc_base_addr + (r))+#define WRITE_REG(sc,r,val)		writel((val), (sc)->sc_base_addr + (r))++#define SAFE_MAX_CHIPS 8+static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];++/*+ * split our buffers up into safe DMAable byte fragments to avoid lockup+ * bug in 1141 HW on rev 1.0.+ */++static int+pci_map_linear(+	struct safe_softc *sc,+	struct safe_operand *buf,+	void *addr,+	int len)+{+	dma_addr_t tmp;+	int chunk, tlen = len;++	tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);++	buf->mapsize += len;+	while (len > 0) {+		chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;+		buf->segs[buf->nsegs].ds_addr = tmp;+		buf->segs[buf->nsegs].ds_len  = chunk;+		buf->segs[buf->nsegs].ds_tlen = tlen;+		buf->nsegs++;+		tmp  += chunk;+		len  -= chunk;+		tlen = 0;+	}+	return 0;+}++/*+ * map in a given uio buffer (great on some arches :-)+ */++static int+pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)+{+	struct iovec *iov = uio->uio_iov;+	int n;++	DPRINTF(("%s()\n", __FUNCTION__));++	buf->mapsize = 0;+	buf->nsegs = 0;++	for (n = 0; n < uio->uio_iovcnt; n++) {+		pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);+		iov++;+	}++	/* identify this buffer by the first segment */+	buf->map = (void *) buf->segs[0].ds_addr;+	return(0);+}++/*+ * map in a given sk_buff+ */++static int+pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)+{+	int i;++	DPRINTF(("%s()\n", __FUNCTION__));++	buf->mapsize = 0;+	buf->nsegs = 0;++	pci_map_linear(sc, buf, skb->data, skb_headlen(skb));++	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {+		pci_map_linear(sc, buf,+				page_address(skb_shinfo(skb)->frags[i].page) ++				                        skb_shinfo(skb)->frags[i].page_offset,+				skb_shinfo(skb)->frags[i].size);+	}++	/* identify this buffer by the first segment */+	buf->map = (void *) buf->segs[0].ds_addr;+	return(0);+}+++#if 0 /* not needed at this time */+static void+pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)+{+	int i;++	DPRINTF(("%s()\n", __FUNCTION__));+	for (i = 0; i < buf->nsegs; i++)+		pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,+				buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);+}+#endif++static void+pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)+{+	int i;+	DPRINTF(("%s()\n", __FUNCTION__));+	for (i = 0; i < buf->nsegs; i++) {+		if (buf->segs[i].ds_tlen) {+			DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));+			pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,+					buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);+			DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));+		}+		buf->segs[i].ds_addr = 0;+		buf->segs[i].ds_len = 0;+		buf->segs[i].ds_tlen = 0;+	}+	buf->nsegs = 0;+	buf->mapsize = 0;+	buf->map = 0;+}+++/*+ * SafeXcel Interrupt routine+ */+static irqreturn_t+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+safe_intr(int irq, void *arg)+#else+safe_intr(int irq, void *arg, struct pt_regs *regs)+#endif+{+	struct safe_softc *sc = arg;+	int stat;+	unsigned long flags;++	stat = READ_REG(sc, SAFE_HM_STAT);++	DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));++	if (stat == 0)		/* shared irq, not for us */+		return IRQ_NONE;++	WRITE_REG(sc, SAFE_HI_CLR, stat);	/* IACK */++	if ((stat & SAFE_INT_PE_DDONE)) {+		/*+		 * Descriptor(s) done; scan the ring and+		 * process completed operations.+		 */+		spin_lock_irqsave(&sc->sc_ringmtx, flags);+		while (sc->sc_back != sc->sc_front) {+			struct safe_ringentry *re = sc->sc_back;++#ifdef SAFE_DEBUG+			if (debug) {+				safe_dump_ringstate(sc, __func__);+				safe_dump_request(sc, __func__, re);+			}+#endif+			/*+			 * safe_process marks ring entries that were allocated+			 * but not used with a csr of zero.  This insures the+			 * ring front pointer never needs to be set backwards+			 * in the event that an entry is allocated but not used+			 * because of a setup error.+			 */+			DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));+			if (re->re_desc.d_csr != 0) {+				if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {+					DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));+					break;+				}+				if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {+					DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));+					break;+				}+				sc->sc_nqchip--;+				safe_callback(sc, re);+			}+			if (++(sc->sc_back) == sc->sc_ringtop)+				sc->sc_back = sc->sc_ring;+		}+		spin_unlock_irqrestore(&sc->sc_ringmtx, flags);+	}++	/*+	 * Check to see if we got any DMA Error+	 */+	if (stat & SAFE_INT_PE_ERROR) {+		printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),+				(int)READ_REG(sc, SAFE_PE_DMASTAT));+		safestats.st_dmaerr++;+		safe_totalreset(sc);+#if 0+		safe_feed(sc);+#endif+	}++	if (sc->sc_needwakeup) {		/* XXX check high watermark */+		int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);+		DPRINTF(("%s: wakeup crypto %x\n", __func__,+			sc->sc_needwakeup));+		sc->sc_needwakeup &= ~wakeup;+		crypto_unblock(sc->sc_cid, wakeup);+	}+	+	return IRQ_HANDLED;+}++/*+ * safe_feed() - post a request to chip+ */+static void+safe_feed(struct safe_softc *sc, struct safe_ringentry *re)+{+	DPRINTF(("%s()\n", __FUNCTION__));+#ifdef SAFE_DEBUG+	if (debug) {+		safe_dump_ringstate(sc, __func__);+		safe_dump_request(sc, __func__, re);+	}+#endif+	sc->sc_nqchip++;+	if (sc->sc_nqchip > safestats.st_maxqchip)+		safestats.st_maxqchip = sc->sc_nqchip;+	/* poke h/w to check descriptor ring, any value can be written */+	WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);+}++#define	N(a)	(sizeof(a) / sizeof (a[0]))+static void+safe_setup_enckey(struct safe_session *ses, caddr_t key)+{+	int i;++	bcopy(key, ses->ses_key, ses->ses_klen / 8);++	/* PE is little-endian, insure proper byte order */+	for (i = 0; i < N(ses->ses_key); i++)+		ses->ses_key[i] = htole32(ses->ses_key[i]);+}++static void+safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)+{+#ifdef HMAC_HACK+	MD5_CTX md5ctx;+	SHA1_CTX sha1ctx;+	int i;+++	for (i = 0; i < klen; i++)+		key[i] ^= HMAC_IPAD_VAL;++	if (algo == CRYPTO_MD5_HMAC) {+		MD5Init(&md5ctx);+		MD5Update(&md5ctx, key, klen);+		MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);+		bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));+	} else {+		SHA1Init(&sha1ctx);+		SHA1Update(&sha1ctx, key, klen);+		SHA1Update(&sha1ctx, hmac_ipad_buffer,+		    SHA1_HMAC_BLOCK_LEN - klen);+		bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));+	}++	for (i = 0; i < klen; i++)+		key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);++	if (algo == CRYPTO_MD5_HMAC) {+		MD5Init(&md5ctx);+		MD5Update(&md5ctx, key, klen);+		MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);+		bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));+	} else {+		SHA1Init(&sha1ctx);+		SHA1Update(&sha1ctx, key, klen);+		SHA1Update(&sha1ctx, hmac_opad_buffer,+		    SHA1_HMAC_BLOCK_LEN - klen);+		bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));+	}++	for (i = 0; i < klen; i++)+		key[i] ^= HMAC_OPAD_VAL;++#if 0+	/*+	 * this code prevents SHA working on a BE host,+	 * so it is obviously wrong.  I think the byte+	 * swap setup we do with the chip fixes this for us+	 */++	/* PE is little-endian, insure proper byte order */+	for (i = 0; i < N(ses->ses_hminner); i++) {+		ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);+		ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);+	}+#endif+#else /* HMAC_HACK */+	printk("safe: md5/sha not implemented\n");+#endif /* HMAC_HACK */+}+#undef N++/*+ * Allocate a new 'session' and return an encoded session id.  'sidp'+ * contains our registration id, and should contain an encoded session+ * id on successful allocation.+ */+static int+safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)+{+	struct safe_softc *sc = device_get_softc(dev);+	struct cryptoini *c, *encini = NULL, *macini = NULL;+	struct safe_session *ses = NULL;+	int sesn;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (sidp == NULL || cri == NULL || sc == NULL)+		return (EINVAL);++	for (c = cri; c != NULL; c = c->cri_next) {+		if (c->cri_alg == CRYPTO_MD5_HMAC ||+		    c->cri_alg == CRYPTO_SHA1_HMAC ||+		    c->cri_alg == CRYPTO_NULL_HMAC) {+			if (macini)+				return (EINVAL);+			macini = c;+		} else if (c->cri_alg == CRYPTO_DES_CBC ||+		    c->cri_alg == CRYPTO_3DES_CBC ||+		    c->cri_alg == CRYPTO_AES_CBC ||+		    c->cri_alg == CRYPTO_NULL_CBC) {+			if (encini)+				return (EINVAL);+			encini = c;+		} else+			return (EINVAL);+	}+	if (encini == NULL && macini == NULL)+		return (EINVAL);+	if (encini) {			/* validate key length */+		switch (encini->cri_alg) {+		case CRYPTO_DES_CBC:+			if (encini->cri_klen != 64)+				return (EINVAL);+			break;+		case CRYPTO_3DES_CBC:+			if (encini->cri_klen != 192)+				return (EINVAL);+			break;+		case CRYPTO_AES_CBC:+			if (encini->cri_klen != 128 &&+			    encini->cri_klen != 192 &&+			    encini->cri_klen != 256)+				return (EINVAL);+			break;+		}+	}++	if (sc->sc_sessions == NULL) {+		ses = sc->sc_sessions = (struct safe_session *)+			kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);+		if (ses == NULL)+			return (ENOMEM);+		memset(ses, 0, sizeof(struct safe_session));+		sesn = 0;+		sc->sc_nsessions = 1;+	} else {+		for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {+			if (sc->sc_sessions[sesn].ses_used == 0) {+				ses = &sc->sc_sessions[sesn];+				break;+			}+		}++		if (ses == NULL) {+			sesn = sc->sc_nsessions;+			ses = (struct safe_session *)+				kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);+			if (ses == NULL)+				return (ENOMEM);+			memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));+			bcopy(sc->sc_sessions, ses, sesn *+			    sizeof(struct safe_session));+			bzero(sc->sc_sessions, sesn *+			    sizeof(struct safe_session));+			kfree(sc->sc_sessions);+			sc->sc_sessions = ses;+			ses = &sc->sc_sessions[sesn];+			sc->sc_nsessions++;+		}+	}++	bzero(ses, sizeof(struct safe_session));+	ses->ses_used = 1;++	if (encini) {+		/* get an IV */+		/* XXX may read fewer than requested */+		read_random(ses->ses_iv, sizeof(ses->ses_iv));++		ses->ses_klen = encini->cri_klen;+		if (encini->cri_key != NULL)+			safe_setup_enckey(ses, encini->cri_key);+	}++	if (macini) {+		ses->ses_mlen = macini->cri_mlen;+		if (ses->ses_mlen == 0) {+			if (macini->cri_alg == CRYPTO_MD5_HMAC)+				ses->ses_mlen = MD5_HASH_LEN;+			else+				ses->ses_mlen = SHA1_HASH_LEN;+		}++		if (macini->cri_key != NULL) {+			safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,+			    macini->cri_klen / 8);+		}+	}++	*sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);+	return (0);+}++/*+ * Deallocate a session.+ */+static int+safe_freesession(device_t dev, u_int64_t tid)+{+	struct safe_softc *sc = device_get_softc(dev);+	int session, ret;+	u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (sc == NULL)+		return (EINVAL);++	session = SAFE_SESSION(sid);+	if (session < sc->sc_nsessions) {+		bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));+		ret = 0;+	} else+		ret = EINVAL;+	return (ret);+}+++static int+safe_process(device_t dev, struct cryptop *crp, int hint)+{+	struct safe_softc *sc = device_get_softc(dev);+	int err = 0, i, nicealign, uniform;+	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;+	int bypass, oplen, ivsize;+	caddr_t iv;+	int16_t coffset;+	struct safe_session *ses;+	struct safe_ringentry *re;+	struct safe_sarec *sa;+	struct safe_pdesc *pd;+	u_int32_t cmd0, cmd1, staterec;+	unsigned long flags;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {+		safestats.st_invalid++;+		return (EINVAL);+	}+	if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {+		safestats.st_badsession++;+		return (EINVAL);+	}++	spin_lock_irqsave(&sc->sc_ringmtx, flags);+	if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {+		safestats.st_ringfull++;+		sc->sc_needwakeup |= CRYPTO_SYMQ;+		spin_unlock_irqrestore(&sc->sc_ringmtx, flags);+		return (ERESTART);+	}+	re = sc->sc_front;++	staterec = re->re_sa.sa_staterec;	/* save */+	/* NB: zero everything but the PE descriptor */+	bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));+	re->re_sa.sa_staterec = staterec;	/* restore */++	re->re_crp = crp;+	re->re_sesn = SAFE_SESSION(crp->crp_sid);++	re->re_src.nsegs = 0;+	re->re_dst.nsegs = 0;++	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		re->re_src_skb = (struct sk_buff *)crp->crp_buf;+		re->re_dst_skb = (struct sk_buff *)crp->crp_buf;+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		re->re_src_io = (struct uio *)crp->crp_buf;+		re->re_dst_io = (struct uio *)crp->crp_buf;+	} else {+		safestats.st_badflags++;+		err = EINVAL;+		goto errout;	/* XXX we don't handle contiguous blocks! */+	}++	sa = &re->re_sa;+	ses = &sc->sc_sessions[re->re_sesn];++	crd1 = crp->crp_desc;+	if (crd1 == NULL) {+		safestats.st_nodesc++;+		err = EINVAL;+		goto errout;+	}+	crd2 = crd1->crd_next;++	cmd0 = SAFE_SA_CMD0_BASIC;		/* basic group operation */+	cmd1 = 0;+	if (crd2 == NULL) {+		if (crd1->crd_alg == CRYPTO_MD5_HMAC ||+		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||+		    crd1->crd_alg == CRYPTO_NULL_HMAC) {+			maccrd = crd1;+			enccrd = NULL;+			cmd0 |= SAFE_SA_CMD0_OP_HASH;+		} else if (crd1->crd_alg == CRYPTO_DES_CBC ||+		    crd1->crd_alg == CRYPTO_3DES_CBC ||+		    crd1->crd_alg == CRYPTO_AES_CBC ||+		    crd1->crd_alg == CRYPTO_NULL_CBC) {+			maccrd = NULL;+			enccrd = crd1;+			cmd0 |= SAFE_SA_CMD0_OP_CRYPT;+		} else {+			safestats.st_badalg++;+			err = EINVAL;+			goto errout;+		}+	} else {+		if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||+		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||+		    crd1->crd_alg == CRYPTO_NULL_HMAC) &&+		    (crd2->crd_alg == CRYPTO_DES_CBC ||+			crd2->crd_alg == CRYPTO_3DES_CBC ||+		        crd2->crd_alg == CRYPTO_AES_CBC ||+		        crd2->crd_alg == CRYPTO_NULL_CBC) &&+		    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {+			maccrd = crd1;+			enccrd = crd2;+		} else if ((crd1->crd_alg == CRYPTO_DES_CBC ||+		    crd1->crd_alg == CRYPTO_3DES_CBC ||+		    crd1->crd_alg == CRYPTO_AES_CBC ||+		    crd1->crd_alg == CRYPTO_NULL_CBC) &&+		    (crd2->crd_alg == CRYPTO_MD5_HMAC ||+			crd2->crd_alg == CRYPTO_SHA1_HMAC ||+			crd2->crd_alg == CRYPTO_NULL_HMAC) &&+		    (crd1->crd_flags & CRD_F_ENCRYPT)) {+			enccrd = crd1;+			maccrd = crd2;+		} else {+			safestats.st_badalg++;+			err = EINVAL;+			goto errout;+		}+		cmd0 |= SAFE_SA_CMD0_OP_BOTH;+	}++	if (enccrd) {+		if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)+			safe_setup_enckey(ses, enccrd->crd_key);++		if (enccrd->crd_alg == CRYPTO_DES_CBC) {+			cmd0 |= SAFE_SA_CMD0_DES;+			cmd1 |= SAFE_SA_CMD1_CBC;+			ivsize = 2*sizeof(u_int32_t);+		} else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {+			cmd0 |= SAFE_SA_CMD0_3DES;+			cmd1 |= SAFE_SA_CMD1_CBC;+			ivsize = 2*sizeof(u_int32_t);+		} else if (enccrd->crd_alg == CRYPTO_AES_CBC) {+			cmd0 |= SAFE_SA_CMD0_AES;+			cmd1 |= SAFE_SA_CMD1_CBC;+			if (ses->ses_klen == 128)+			     cmd1 |=  SAFE_SA_CMD1_AES128;+			else if (ses->ses_klen == 192)+			     cmd1 |=  SAFE_SA_CMD1_AES192;+			else+			     cmd1 |=  SAFE_SA_CMD1_AES256;+			ivsize = 4*sizeof(u_int32_t);+		} else {+			cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;+			ivsize = 0;+		}++		/*+		 * Setup encrypt/decrypt state.  When using basic ops+		 * we can't use an inline IV because hash/crypt offset+		 * must be from the end of the IV to the start of the+		 * crypt data and this leaves out the preceding header+		 * from the hash calculation.  Instead we place the IV+		 * in the state record and set the hash/crypt offset to+		 * copy both the header+IV.+		 */+		if (enccrd->crd_flags & CRD_F_ENCRYPT) {+			cmd0 |= SAFE_SA_CMD0_OUTBOUND;++			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)+				iv = enccrd->crd_iv;+			else+				iv = (caddr_t) ses->ses_iv;+			if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {+				crypto_copyback(crp->crp_flags, crp->crp_buf,+				    enccrd->crd_inject, ivsize, iv);+			}+			bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);+			/* make iv LE */+			for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)+				re->re_sastate.sa_saved_iv[i] =+					cpu_to_le32(re->re_sastate.sa_saved_iv[i]);+			cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;+			re->re_flags |= SAFE_QFLAGS_COPYOUTIV;+		} else {+			cmd0 |= SAFE_SA_CMD0_INBOUND;++			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {+				bcopy(enccrd->crd_iv,+					re->re_sastate.sa_saved_iv, ivsize);+			} else {+				crypto_copydata(crp->crp_flags, crp->crp_buf,+				    enccrd->crd_inject, ivsize,+				    (caddr_t)re->re_sastate.sa_saved_iv);+			}+			/* make iv LE */+			for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)+				re->re_sastate.sa_saved_iv[i] =+					cpu_to_le32(re->re_sastate.sa_saved_iv[i]);+			cmd0 |= SAFE_SA_CMD0_IVLD_STATE;+		}+		/*+		 * For basic encryption use the zero pad algorithm.+		 * This pads results to an 8-byte boundary and+		 * suppresses padding verification for inbound (i.e.+		 * decrypt) operations.+		 *+		 * NB: Not sure if the 8-byte pad boundary is a problem.+		 */+		cmd0 |= SAFE_SA_CMD0_PAD_ZERO;++		/* XXX assert key bufs have the same size */+		bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));+	}++	if (maccrd) {+		if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {+			safe_setup_mackey(ses, maccrd->crd_alg,+			    maccrd->crd_key, maccrd->crd_klen / 8);+		}++		if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {+			cmd0 |= SAFE_SA_CMD0_MD5;+			cmd1 |= SAFE_SA_CMD1_HMAC;	/* NB: enable HMAC */+		} else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {+			cmd0 |= SAFE_SA_CMD0_SHA1;+			cmd1 |= SAFE_SA_CMD1_HMAC;	/* NB: enable HMAC */+		} else {+			cmd0 |= SAFE_SA_CMD0_HASH_NULL;+		}+		/*+		 * Digest data is loaded from the SA and the hash+		 * result is saved to the state block where we+		 * retrieve it for return to the caller.+		 */+		/* XXX assert digest bufs have the same size */+		bcopy(ses->ses_hminner, sa->sa_indigest,+			sizeof(sa->sa_indigest));+		bcopy(ses->ses_hmouter, sa->sa_outdigest,+			sizeof(sa->sa_outdigest));++		cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;+		re->re_flags |= SAFE_QFLAGS_COPYOUTICV;+	}++	if (enccrd && maccrd) {+		/*+		 * The offset from hash data to the start of+		 * crypt data is the difference in the skips.+		 */+		bypass = maccrd->crd_skip;+		coffset = enccrd->crd_skip - maccrd->crd_skip;+		if (coffset < 0) {+			DPRINTF(("%s: hash does not precede crypt; "+				"mac skip %u enc skip %u\n",+				__func__, maccrd->crd_skip, enccrd->crd_skip));+			safestats.st_skipmismatch++;+			err = EINVAL;+			goto errout;+		}+		oplen = enccrd->crd_skip + enccrd->crd_len;+		if (maccrd->crd_skip + maccrd->crd_len != oplen) {+			DPRINTF(("%s: hash amount %u != crypt amount %u\n",+				__func__, maccrd->crd_skip + maccrd->crd_len,+				oplen));+			safestats.st_lenmismatch++;+			err = EINVAL;+			goto errout;+		}+#ifdef SAFE_DEBUG+		if (debug) {+			printf("mac: skip %d, len %d, inject %d\n",+			    maccrd->crd_skip, maccrd->crd_len,+			    maccrd->crd_inject);+			printf("enc: skip %d, len %d, inject %d\n",+			    enccrd->crd_skip, enccrd->crd_len,+			    enccrd->crd_inject);+			printf("bypass %d coffset %d oplen %d\n",+				bypass, coffset, oplen);+		}+#endif+		if (coffset & 3) {	/* offset must be 32-bit aligned */+			DPRINTF(("%s: coffset %u misaligned\n",+				__func__, coffset));+			safestats.st_coffmisaligned++;+			err = EINVAL;+			goto errout;+		}+		coffset >>= 2;+		if (coffset > 255) {	/* offset must be <256 dwords */+			DPRINTF(("%s: coffset %u too big\n",+				__func__, coffset));+			safestats.st_cofftoobig++;+			err = EINVAL;+			goto errout;+		}+		/*+		 * Tell the hardware to copy the header to the output.+		 * The header is defined as the data from the end of+		 * the bypass to the start of data to be encrypted. +		 * Typically this is the inline IV.  Note that you need+		 * to do this even if src+dst are the same; it appears+		 * that w/o this bit the crypted data is written+		 * immediately after the bypass data.+		 */+		cmd1 |= SAFE_SA_CMD1_HDRCOPY;+		/*+		 * Disable IP header mutable bit handling.  This is+		 * needed to get correct HMAC calculations.+		 */+		cmd1 |= SAFE_SA_CMD1_MUTABLE;+	} else {+		if (enccrd) {+			bypass = enccrd->crd_skip;+			oplen = bypass + enccrd->crd_len;+		} else {+			bypass = maccrd->crd_skip;+			oplen = bypass + maccrd->crd_len;+		}+		coffset = 0;+	}+	/* XXX verify multiple of 4 when using s/g */+	if (bypass > 96) {		/* bypass offset must be <= 96 bytes */+		DPRINTF(("%s: bypass %u too big\n", __func__, bypass));+		safestats.st_bypasstoobig++;+		err = EINVAL;+		goto errout;+	}++	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {+			safestats.st_noload++;+			err = ENOMEM;+			goto errout;+		}+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {+			safestats.st_noload++;+			err = ENOMEM;+			goto errout;+		}+	}+	nicealign = safe_dmamap_aligned(sc, &re->re_src);+	uniform = safe_dmamap_uniform(sc, &re->re_src);++	DPRINTF(("src nicealign %u uniform %u nsegs %u\n",+		nicealign, uniform, re->re_src.nsegs));+	if (re->re_src.nsegs > 1) {+		re->re_desc.d_src = sc->sc_spalloc.dma_paddr ++			((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);+		for (i = 0; i < re->re_src_nsegs; i++) {+			/* NB: no need to check if there's space */+			pd = sc->sc_spfree;+			if (++(sc->sc_spfree) == sc->sc_springtop)+				sc->sc_spfree = sc->sc_spring;++			KASSERT((pd->pd_flags&3) == 0 ||+				(pd->pd_flags&3) == SAFE_PD_DONE,+				("bogus source particle descriptor; flags %x",+				pd->pd_flags));+			pd->pd_addr = re->re_src_segs[i].ds_addr;+			pd->pd_size = re->re_src_segs[i].ds_len;+			pd->pd_flags = SAFE_PD_READY;+		}+		cmd0 |= SAFE_SA_CMD0_IGATHER;+	} else {+		/*+		 * No need for gather, reference the operand directly.+		 */+		re->re_desc.d_src = re->re_src_segs[0].ds_addr;+	}++	if (enccrd == NULL && maccrd != NULL) {+		/*+		 * Hash op; no destination needed.+		 */+	} else {+		if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {+			if (!nicealign) {+				safestats.st_iovmisaligned++;+				err = EINVAL;+				goto errout;+			}+			if (uniform != 1) {+				device_printf(sc->sc_dev, "!uniform source\n");+				if (!uniform) {+					/*+					 * There's no way to handle the DMA+					 * requirements with this uio.  We+					 * could create a separate DMA area for+					 * the result and then copy it back,+					 * but for now we just bail and return+					 * an error.  Note that uio requests+					 * > SAFE_MAX_DSIZE are handled because+					 * the DMA map and segment list for the+					 * destination wil result in a+					 * destination particle list that does+					 * the necessary scatter DMA.+					 */ +					safestats.st_iovnotuniform++;+					err = EINVAL;+					goto errout;+				}+			} else+				re->re_dst = re->re_src;+		} else {+			safestats.st_badflags++;+			err = EINVAL;+			goto errout;+		}++		if (re->re_dst.nsegs > 1) {+			re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr ++			    ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);+			for (i = 0; i < re->re_dst_nsegs; i++) {+				pd = sc->sc_dpfree;+				KASSERT((pd->pd_flags&3) == 0 ||+					(pd->pd_flags&3) == SAFE_PD_DONE,+					("bogus dest particle descriptor; flags %x",+						pd->pd_flags));+				if (++(sc->sc_dpfree) == sc->sc_dpringtop)+					sc->sc_dpfree = sc->sc_dpring;+				pd->pd_addr = re->re_dst_segs[i].ds_addr;+				pd->pd_flags = SAFE_PD_READY;+			}+			cmd0 |= SAFE_SA_CMD0_OSCATTER;+		} else {+			/*+			 * No need for scatter, reference the operand directly.+			 */+			re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;+		}+	}++	/*+	 * All done with setup; fillin the SA command words+	 * and the packet engine descriptor.  The operation+	 * is now ready for submission to the hardware.+	 */+	sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;+	sa->sa_cmd1 = cmd1+		    | (coffset << SAFE_SA_CMD1_OFFSET_S)+		    | SAFE_SA_CMD1_SAREV1	/* Rev 1 SA data structure */+		    | SAFE_SA_CMD1_SRPCI+		    ;+	/*+	 * NB: the order of writes is important here.  In case the+	 * chip is scanning the ring because of an outstanding request+	 * it might nab this one too.  In that case we need to make+	 * sure the setup is complete before we write the length+	 * field of the descriptor as it signals the descriptor is+	 * ready for processing.+	 */+	re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;+	if (maccrd)+		re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;+	wmb();+	re->re_desc.d_len = oplen+			  | SAFE_PE_LEN_READY+			  | (bypass << SAFE_PE_LEN_BYPASS_S)+			  ;++	safestats.st_ipackets++;+	safestats.st_ibytes += oplen;++	if (++(sc->sc_front) == sc->sc_ringtop)+		sc->sc_front = sc->sc_ring;++	/* XXX honor batching */+	safe_feed(sc, re);+	spin_unlock_irqrestore(&sc->sc_ringmtx, flags);+	return (0);++errout:+	if (re->re_src.map != re->re_dst.map)+		pci_unmap_operand(sc, &re->re_dst);+	if (re->re_src.map)+		pci_unmap_operand(sc, &re->re_src);+	spin_unlock_irqrestore(&sc->sc_ringmtx, flags);+	if (err != ERESTART) {+		crp->crp_etype = err;+		crypto_done(crp);+	} else {+		sc->sc_needwakeup |= CRYPTO_SYMQ;+	}+	return (err);+}++static void+safe_callback(struct safe_softc *sc, struct safe_ringentry *re)+{+	struct cryptop *crp = (struct cryptop *)re->re_crp;+	struct cryptodesc *crd;++	DPRINTF(("%s()\n", __FUNCTION__));++	safestats.st_opackets++;+	safestats.st_obytes += re->re_dst.mapsize;++	if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {+		device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",+			re->re_desc.d_csr,+			re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);+		safestats.st_peoperr++;+		crp->crp_etype = EIO;		/* something more meaningful? */+	}++	if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)+		pci_unmap_operand(sc, &re->re_dst);+	pci_unmap_operand(sc, &re->re_src);++	/* +	 * If result was written to a differet mbuf chain, swap+	 * it in as the return value and reclaim the original.+	 */+	if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {+		device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");+		/* kfree_skb(skb) */+		/* crp->crp_buf = (caddr_t)re->re_dst_skb */+		return;+	}++	if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {+		/* copy out IV for future use */+		for (crd = crp->crp_desc; crd; crd = crd->crd_next) {+			int i;+			int ivsize;++			if (crd->crd_alg == CRYPTO_DES_CBC ||+			    crd->crd_alg == CRYPTO_3DES_CBC) {+				ivsize = 2*sizeof(u_int32_t);+			} else if (crd->crd_alg == CRYPTO_AES_CBC) {+				ivsize = 4*sizeof(u_int32_t);+			} else+				continue;+			crypto_copydata(crp->crp_flags, crp->crp_buf,+			    crd->crd_skip + crd->crd_len - ivsize, ivsize,+			    (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);+			for (i = 0;+					i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);+					i++)+				sc->sc_sessions[re->re_sesn].ses_iv[i] =+					cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);+			break;+		}+	}++	if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {+		/* copy out ICV result */+		for (crd = crp->crp_desc; crd; crd = crd->crd_next) {+			if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||+			    crd->crd_alg == CRYPTO_SHA1_HMAC ||+			    crd->crd_alg == CRYPTO_NULL_HMAC))+				continue;+			if (crd->crd_alg == CRYPTO_SHA1_HMAC) {+				/*+				 * SHA-1 ICV's are byte-swapped; fix 'em up+				 * before copy them to their destination.+				 */+				re->re_sastate.sa_saved_indigest[0] =+					cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);+				re->re_sastate.sa_saved_indigest[1] = +					cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);+				re->re_sastate.sa_saved_indigest[2] =+					cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);+			} else {+				re->re_sastate.sa_saved_indigest[0] =+					cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);+				re->re_sastate.sa_saved_indigest[1] = +					cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);+				re->re_sastate.sa_saved_indigest[2] =+					cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);+			}+			crypto_copyback(crp->crp_flags, crp->crp_buf,+			    crd->crd_inject,+			    sc->sc_sessions[re->re_sesn].ses_mlen,+			    (caddr_t)re->re_sastate.sa_saved_indigest);+			break;+		}+	}+	crypto_done(crp);+}+++#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)+#define	SAFE_RNG_MAXWAIT	1000++static void+safe_rng_init(struct safe_softc *sc)+{+	u_int32_t w, v;+	int i;++	DPRINTF(("%s()\n", __FUNCTION__));++	WRITE_REG(sc, SAFE_RNG_CTRL, 0);+	/* use default value according to the manual */+	WRITE_REG(sc, SAFE_RNG_CNFG, 0x834);	/* magic from SafeNet */+	WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);++	/*+	 * There is a bug in rev 1.0 of the 1140 that when the RNG+	 * is brought out of reset the ready status flag does not+	 * work until the RNG has finished its internal initialization.+	 *+	 * So in order to determine the device is through its+	 * initialization we must read the data register, using the+	 * status reg in the read in case it is initialized.  Then read+	 * the data register until it changes from the first read.+	 * Once it changes read the data register until it changes+	 * again.  At this time the RNG is considered initialized. +	 * This could take between 750ms - 1000ms in time.+	 */+	i = 0;+	w = READ_REG(sc, SAFE_RNG_OUT);+	do {+		v = READ_REG(sc, SAFE_RNG_OUT);+		if (v != w) {+			w = v;+			break;+		}+		DELAY(10);+	} while (++i < SAFE_RNG_MAXWAIT);++	/* Wait Until data changes again */+	i = 0;+	do {+		v = READ_REG(sc, SAFE_RNG_OUT);+		if (v != w)+			break;+		DELAY(10);+	} while (++i < SAFE_RNG_MAXWAIT);+}++static __inline void+safe_rng_disable_short_cycle(struct safe_softc *sc)+{+	DPRINTF(("%s()\n", __FUNCTION__));++	WRITE_REG(sc, SAFE_RNG_CTRL,+		READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);+}++static __inline void+safe_rng_enable_short_cycle(struct safe_softc *sc)+{+	DPRINTF(("%s()\n", __FUNCTION__));++	WRITE_REG(sc, SAFE_RNG_CTRL, +		READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);+}++static __inline u_int32_t+safe_rng_read(struct safe_softc *sc)+{+	int i;++	i = 0;+	while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)+		;+	return READ_REG(sc, SAFE_RNG_OUT);+}++static int+safe_read_random(void *arg, u_int32_t *buf, int maxwords)+{+	struct safe_softc *sc = (struct safe_softc *) arg;+	int i, rc;++	DPRINTF(("%s()\n", __FUNCTION__));+	+	safestats.st_rng++;+	/*+	 * Fetch the next block of data.+	 */+	if (maxwords > safe_rngbufsize)+		maxwords = safe_rngbufsize;+	if (maxwords > SAFE_RNG_MAXBUFSIZ)+		maxwords = SAFE_RNG_MAXBUFSIZ;+retry:+	/* read as much as we can */+	for (rc = 0; rc < maxwords; rc++) {+		if (READ_REG(sc, SAFE_RNG_STAT) != 0)+			break;+		buf[rc] = READ_REG(sc, SAFE_RNG_OUT);+	}+	if (rc == 0)+		return 0;+	/*+	 * Check the comparator alarm count and reset the h/w if+	 * it exceeds our threshold.  This guards against the+	 * hardware oscillators resonating with external signals.+	 */+	if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {+		u_int32_t freq_inc, w;++		DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,+			(unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));+		safestats.st_rngalarm++;+		safe_rng_enable_short_cycle(sc);+		freq_inc = 18;+		for (i = 0; i < 64; i++) {+			w = READ_REG(sc, SAFE_RNG_CNFG);+			freq_inc = ((w + freq_inc) & 0x3fL);+			w = ((w & ~0x3fL) | freq_inc);+			WRITE_REG(sc, SAFE_RNG_CNFG, w);++			WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);++			(void) safe_rng_read(sc);+			DELAY(25);++			if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {+				safe_rng_disable_short_cycle(sc);+				goto retry;+			}+			freq_inc = 1;+		}+		safe_rng_disable_short_cycle(sc);+	} else+		WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);++	return(rc);+}+#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */+++/*+ * Resets the board.  Values in the regesters are left as is+ * from the reset (i.e. initial values are assigned elsewhere).+ */+static void+safe_reset_board(struct safe_softc *sc)+{+	u_int32_t v;+	/*+	 * Reset the device.  The manual says no delay+	 * is needed between marking and clearing reset.+	 */+	DPRINTF(("%s()\n", __FUNCTION__));++	v = READ_REG(sc, SAFE_PE_DMACFG) &~+		(SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |+		 SAFE_PE_DMACFG_SGRESET);+	WRITE_REG(sc, SAFE_PE_DMACFG, v+				    | SAFE_PE_DMACFG_PERESET+				    | SAFE_PE_DMACFG_PDRRESET+				    | SAFE_PE_DMACFG_SGRESET);+	WRITE_REG(sc, SAFE_PE_DMACFG, v);+}++/*+ * Initialize registers we need to touch only once.+ */+static void+safe_init_board(struct safe_softc *sc)+{+	u_int32_t v, dwords;++	DPRINTF(("%s()\n", __FUNCTION__));++	v = READ_REG(sc, SAFE_PE_DMACFG);+	v &=~ (   SAFE_PE_DMACFG_PEMODE+			| SAFE_PE_DMACFG_FSENA		/* failsafe enable */+			| SAFE_PE_DMACFG_GPRPCI		/* gather ring on PCI */+			| SAFE_PE_DMACFG_SPRPCI		/* scatter ring on PCI */+			| SAFE_PE_DMACFG_ESDESC		/* endian-swap descriptors */+			| SAFE_PE_DMACFG_ESPDESC	/* endian-swap part. desc's */+			| SAFE_PE_DMACFG_ESSA		/* endian-swap SA's */+			| SAFE_PE_DMACFG_ESPACKET	/* swap the packet data */+		  );+	v |= SAFE_PE_DMACFG_FSENA		/* failsafe enable */+	  |  SAFE_PE_DMACFG_GPRPCI		/* gather ring on PCI */+	  |  SAFE_PE_DMACFG_SPRPCI		/* scatter ring on PCI */+	  |  SAFE_PE_DMACFG_ESDESC		/* endian-swap descriptors */+	  |  SAFE_PE_DMACFG_ESPDESC		/* endian-swap part. desc's */+	  |  SAFE_PE_DMACFG_ESSA		/* endian-swap SA's */+#if 0+	  |  SAFE_PE_DMACFG_ESPACKET    /* swap the packet data */+#endif+	  ;+	WRITE_REG(sc, SAFE_PE_DMACFG, v);++#ifdef __BIG_ENDIAN+	/* tell the safenet that we are 4321 and not 1234 */+	WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);+#endif++	if (sc->sc_chiprev == SAFE_REV(1,0)) {+		/*+		 * Avoid large PCI DMA transfers.  Rev 1.0 has a bug where+		 * "target mode transfers" done while the chip is DMA'ing+		 * >1020 bytes cause the hardware to lockup.  To avoid this+		 * we reduce the max PCI transfer size and use small source+		 * particle descriptors (<= 256 bytes).+		 */+		WRITE_REG(sc, SAFE_DMA_CFG, 256);+		device_printf(sc->sc_dev,+			"Reduce max DMA size to %u words for rev %u.%u WAR\n",+			(unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),+			(unsigned) SAFE_REV_MAJ(sc->sc_chiprev),+			(unsigned) SAFE_REV_MIN(sc->sc_chiprev));+		sc->sc_max_dsize = 256;+	} else {+		sc->sc_max_dsize = SAFE_MAX_DSIZE;+	}++	/* NB: operands+results are overlaid */+	WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);+	WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);+	/*+	 * Configure ring entry size and number of items in the ring.+	 */+	KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,+		("PE ring entry not 32-bit aligned!"));+	dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);+	WRITE_REG(sc, SAFE_PE_RINGCFG,+		(dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);+	WRITE_REG(sc, SAFE_PE_RINGPOLL, 0);	/* disable polling */++	WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);+	WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);+	WRITE_REG(sc, SAFE_PE_PARTSIZE,+		(SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);+	/*+	 * NB: destination particles are fixed size.  We use+	 *     an mbuf cluster and require all results go to+	 *     clusters or smaller.+	 */+	WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);++	/* it's now safe to enable PE mode, do it */+	WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);++	/*+	 * Configure hardware to use level-triggered interrupts and+	 * to interrupt after each descriptor is processed.+	 */+	WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);+	WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);+	WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);+	WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);+}+++/*+ * Clean up after a chip crash.+ * It is assumed that the caller in splimp()+ */+static void+safe_cleanchip(struct safe_softc *sc)+{+	DPRINTF(("%s()\n", __FUNCTION__));++	if (sc->sc_nqchip != 0) {+		struct safe_ringentry *re = sc->sc_back;++		while (re != sc->sc_front) {+			if (re->re_desc.d_csr != 0)+				safe_free_entry(sc, re);+			if (++re == sc->sc_ringtop)+				re = sc->sc_ring;+		}+		sc->sc_back = re;+		sc->sc_nqchip = 0;+	}+}++/*+ * free a safe_q+ * It is assumed that the caller is within splimp().+ */+static int+safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)+{+	struct cryptop *crp;++	DPRINTF(("%s()\n", __FUNCTION__));++	/*+	 * Free header MCR+	 */+	if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))+#ifdef NOTYET+		m_freem(re->re_dst_m);+#else+		printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);+#endif++	crp = (struct cryptop *)re->re_crp;+	+	re->re_desc.d_csr = 0;+	+	crp->crp_etype = EFAULT;+	crypto_done(crp);+	return(0);+}++/*+ * Routine to reset the chip and clean up.+ * It is assumed that the caller is in splimp()+ */+static void+safe_totalreset(struct safe_softc *sc)+{+	DPRINTF(("%s()\n", __FUNCTION__));++	safe_reset_board(sc);+	safe_init_board(sc);+	safe_cleanchip(sc);+}++/*+ * Is the operand suitable aligned for direct DMA.  Each+ * segment must be aligned on a 32-bit boundary and all+ * but the last segment must be a multiple of 4 bytes.+ */+static int+safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)+{+	int i;++	DPRINTF(("%s()\n", __FUNCTION__));++	for (i = 0; i < op->nsegs; i++) {+		if (op->segs[i].ds_addr & 3)+			return (0);+		if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))+			return (0);+	}+	return (1);+}++/*+ * Is the operand suitable for direct DMA as the destination+ * of an operation.  The hardware requires that each ``particle''+ * but the last in an operation result have the same size.  We+ * fix that size at SAFE_MAX_DSIZE bytes.  This routine returns+ * 0 if some segment is not a multiple of of this size, 1 if all+ * segments are exactly this size, or 2 if segments are at worst+ * a multple of this size.+ */+static int+safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)+{+	int result = 1;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (op->nsegs > 0) {+		int i;++		for (i = 0; i < op->nsegs-1; i++) {+			if (op->segs[i].ds_len % sc->sc_max_dsize)+				return (0);+			if (op->segs[i].ds_len != sc->sc_max_dsize)+				result = 2;+		}+	}+	return (result);+}++static int+safe_kprocess(device_t dev, struct cryptkop *krp, int hint)+{+	struct safe_softc *sc = device_get_softc(dev);+	struct safe_pkq *q;+	unsigned long flags;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (sc == NULL) {+		krp->krp_status = EINVAL;+		goto err;+	}++	if (krp->krp_op != CRK_MOD_EXP) {+		krp->krp_status = EOPNOTSUPP;+		goto err;+	}++	q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);+	if (q == NULL) {+		krp->krp_status = ENOMEM;+		goto err;+	}+	memset(q, 0, sizeof(*q));+	q->pkq_krp = krp;+	INIT_LIST_HEAD(&q->pkq_list);++	spin_lock_irqsave(&sc->sc_pkmtx, flags);+	list_add_tail(&q->pkq_list, &sc->sc_pkq);+	safe_kfeed(sc);+	spin_unlock_irqrestore(&sc->sc_pkmtx, flags);+	return (0);++err:+	crypto_kdone(krp);+	return (0);+}++#define	SAFE_CRK_PARAM_BASE	0+#define	SAFE_CRK_PARAM_EXP	1+#define	SAFE_CRK_PARAM_MOD	2++static int+safe_kstart(struct safe_softc *sc)+{+	struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;+	int exp_bits, mod_bits, base_bits;+	u_int32_t op, a_off, b_off, c_off, d_off;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {+		krp->krp_status = EINVAL;+		return (1);+	}++	base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);+	if (base_bits > 2048)+		goto too_big;+	if (base_bits <= 0)		/* 5. base not zero */+		goto too_small;++	exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);+	if (exp_bits > 2048)+		goto too_big;+	if (exp_bits <= 0)		/* 1. exponent word length > 0 */+		goto too_small;		/* 4. exponent not zero */++	mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);+	if (mod_bits > 2048)+		goto too_big;+	if (mod_bits <= 32)		/* 2. modulus word length > 1 */+		goto too_small;		/* 8. MSW of modulus != zero */+	if (mod_bits < exp_bits)	/* 3 modulus len >= exponent len */+		goto too_small;+	if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)+		goto bad_domain;	/* 6. modulus is odd */+	if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)+		goto too_small;		/* make sure result will fit */++	/* 7. modulus > base */+	if (mod_bits < base_bits)+		goto too_small;+	if (mod_bits == base_bits) {+		u_int8_t *basep, *modp;+		int i;++		basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p ++		    ((base_bits + 7) / 8) - 1;+		modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p ++		    ((mod_bits + 7) / 8) - 1;+		+		for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {+			if (*modp < *basep)+				goto too_small;+			if (*modp > *basep)+				break;+		}+	}++	/* And on the 9th step, he rested. */++	WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);+	WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);+	if (mod_bits > 1024) {+		op = SAFE_PK_FUNC_EXP4;+		a_off = 0x000;+		b_off = 0x100;+		c_off = 0x200;+		d_off = 0x300;+	} else {+		op = SAFE_PK_FUNC_EXP16;+		a_off = 0x000;+		b_off = 0x080;+		c_off = 0x100;+		d_off = 0x180;+	}+	sc->sc_pk_reslen = b_off - a_off;+	sc->sc_pk_resoff = d_off;++	/* A is exponent, B is modulus, C is base, D is result */+	safe_kload_reg(sc, a_off, b_off - a_off,+	    &krp->krp_param[SAFE_CRK_PARAM_EXP]);+	WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);+	safe_kload_reg(sc, b_off, b_off - a_off,+	    &krp->krp_param[SAFE_CRK_PARAM_MOD]);+	WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);+	safe_kload_reg(sc, c_off, b_off - a_off,+	    &krp->krp_param[SAFE_CRK_PARAM_BASE]);+	WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);+	WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);++	WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);++	return (0);++too_big:+	krp->krp_status = E2BIG;+	return (1);+too_small:+	krp->krp_status = ERANGE;+	return (1);+bad_domain:+	krp->krp_status = EDOM;+	return (1);+}++static int+safe_ksigbits(struct safe_softc *sc, struct crparam *cr)+{+	u_int plen = (cr->crp_nbits + 7) / 8;+	int i, sig = plen * 8;+	u_int8_t c, *p = cr->crp_p;++	DPRINTF(("%s()\n", __FUNCTION__));++	for (i = plen - 1; i >= 0; i--) {+		c = p[i];+		if (c != 0) {+			while ((c & 0x80) == 0) {+				sig--;+				c <<= 1;+			}+			break;+		}+		sig -= 8;+	}+	return (sig);+}++static void+safe_kfeed(struct safe_softc *sc)+{+	struct safe_pkq *q, *tmp;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)+		return;+	if (sc->sc_pkq_cur != NULL)+		return;+	list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {+		sc->sc_pkq_cur = q;+		list_del(&q->pkq_list);+		if (safe_kstart(sc) != 0) {+			crypto_kdone(q->pkq_krp);+			kfree(q);+			sc->sc_pkq_cur = NULL;+		} else {+			/* op started, start polling */+			mod_timer(&sc->sc_pkto, jiffies + 1);+			break;+		}+	}+}++static void+safe_kpoll(unsigned long arg)+{+	struct safe_softc *sc = NULL;+	struct safe_pkq *q;+	struct crparam *res;+	int i;+	u_int32_t buf[64];+	unsigned long flags;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (arg >= SAFE_MAX_CHIPS)+		return;+	sc = safe_chip_idx[arg];+	if (!sc) {+		DPRINTF(("%s() - bad callback\n", __FUNCTION__));+		return;+	}++	spin_lock_irqsave(&sc->sc_pkmtx, flags);+	if (sc->sc_pkq_cur == NULL)+		goto out;+	if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {+		/* still running, check back later */+		mod_timer(&sc->sc_pkto, jiffies + 1);+		goto out;+	}++	q = sc->sc_pkq_cur;+	res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];+	bzero(buf, sizeof(buf));+	bzero(res->crp_p, (res->crp_nbits + 7) / 8);+	for (i = 0; i < sc->sc_pk_reslen >> 2; i++)+		buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START ++		    sc->sc_pk_resoff + (i << 2)));+	bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);+	/*+	 * reduce the bits that need copying if possible+	 */+	res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);+	res->crp_nbits = safe_ksigbits(sc, res);++	for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)+		WRITE_REG(sc, i, 0);++	crypto_kdone(q->pkq_krp);+	kfree(q);+	sc->sc_pkq_cur = NULL;++	safe_kfeed(sc);+out:+	spin_unlock_irqrestore(&sc->sc_pkmtx, flags);+}++static void+safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,+    struct crparam *n)+{+	u_int32_t buf[64], i;++	DPRINTF(("%s()\n", __FUNCTION__));++	bzero(buf, sizeof(buf));+	bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);++	for (i = 0; i < len >> 2; i++)+		WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),+		    cpu_to_le32(buf[i]));+}++#ifdef SAFE_DEBUG+static void+safe_dump_dmastatus(struct safe_softc *sc, const char *tag)+{+	printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"+		, tag+		, READ_REG(sc, SAFE_DMA_ENDIAN)+		, READ_REG(sc, SAFE_DMA_SRCADDR)+		, READ_REG(sc, SAFE_DMA_DSTADDR)+		, READ_REG(sc, SAFE_DMA_STAT)+	);+}++static void+safe_dump_intrstate(struct safe_softc *sc, const char *tag)+{+	printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"+		, tag+		, READ_REG(sc, SAFE_HI_CFG)+		, READ_REG(sc, SAFE_HI_MASK)+		, READ_REG(sc, SAFE_HI_DESC_CNT)+		, READ_REG(sc, SAFE_HU_STAT)+		, READ_REG(sc, SAFE_HM_STAT)+	);+}++static void+safe_dump_ringstate(struct safe_softc *sc, const char *tag)+{+	u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);++	/* NB: assume caller has lock on ring */+	printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",+		tag,+		estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),+		(unsigned long)(sc->sc_back - sc->sc_ring),+		(unsigned long)(sc->sc_front - sc->sc_ring));+}++static void+safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)+{+	int ix, nsegs;++	ix = re - sc->sc_ring;+	printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"+		, tag+		, re, ix+		, re->re_desc.d_csr+		, re->re_desc.d_src+		, re->re_desc.d_dst+		, re->re_desc.d_sa+		, re->re_desc.d_len+	);+	if (re->re_src.nsegs > 1) {+		ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /+			sizeof(struct safe_pdesc);+		for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {+			printf(" spd[%u] %p: %p size %u flags %x"+				, ix, &sc->sc_spring[ix]+				, (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr+				, sc->sc_spring[ix].pd_size+				, sc->sc_spring[ix].pd_flags+			);+			if (sc->sc_spring[ix].pd_size == 0)+				printf(" (zero!)");+			printf("\n");+			if (++ix == SAFE_TOTAL_SPART)+				ix = 0;+		}+	}+	if (re->re_dst.nsegs > 1) {+		ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /+			sizeof(struct safe_pdesc);+		for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {+			printf(" dpd[%u] %p: %p flags %x\n"+				, ix, &sc->sc_dpring[ix]+				, (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr+				, sc->sc_dpring[ix].pd_flags+			);+			if (++ix == SAFE_TOTAL_DPART)+				ix = 0;+		}+	}+	printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",+		re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);+	printf("sa: key %x %x %x %x %x %x %x %x\n"+		, re->re_sa.sa_key[0]+		, re->re_sa.sa_key[1]+		, re->re_sa.sa_key[2]+		, re->re_sa.sa_key[3]+		, re->re_sa.sa_key[4]+		, re->re_sa.sa_key[5]+		, re->re_sa.sa_key[6]+		, re->re_sa.sa_key[7]+	);+	printf("sa: indigest %x %x %x %x %x\n"+		, re->re_sa.sa_indigest[0]+		, re->re_sa.sa_indigest[1]+		, re->re_sa.sa_indigest[2]+		, re->re_sa.sa_indigest[3]+		, re->re_sa.sa_indigest[4]+	);+	printf("sa: outdigest %x %x %x %x %x\n"+		, re->re_sa.sa_outdigest[0]+		, re->re_sa.sa_outdigest[1]+		, re->re_sa.sa_outdigest[2]+		, re->re_sa.sa_outdigest[3]+		, re->re_sa.sa_outdigest[4]+	);+	printf("sr: iv %x %x %x %x\n"+		, re->re_sastate.sa_saved_iv[0]+		, re->re_sastate.sa_saved_iv[1]+		, re->re_sastate.sa_saved_iv[2]+		, re->re_sastate.sa_saved_iv[3]+	);+	printf("sr: hashbc %u indigest %x %x %x %x %x\n"+		, re->re_sastate.sa_saved_hashbc+		, re->re_sastate.sa_saved_indigest[0]+		, re->re_sastate.sa_saved_indigest[1]+		, re->re_sastate.sa_saved_indigest[2]+		, re->re_sastate.sa_saved_indigest[3]+		, re->re_sastate.sa_saved_indigest[4]+	);+}++static void+safe_dump_ring(struct safe_softc *sc, const char *tag)+{+	unsigned long flags;++	spin_lock_irqsave(&sc->sc_ringmtx, flags);+	printf("\nSafeNet Ring State:\n");+	safe_dump_intrstate(sc, tag);+	safe_dump_dmastatus(sc, tag);+	safe_dump_ringstate(sc, tag);+	if (sc->sc_nqchip) {+		struct safe_ringentry *re = sc->sc_back;+		do {+			safe_dump_request(sc, tag, re);+			if (++re == sc->sc_ringtop)+				re = sc->sc_ring;+		} while (re != sc->sc_front);+	}+	spin_unlock_irqrestore(&sc->sc_ringmtx, flags);+}+#endif /* SAFE_DEBUG */+++static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)+{+	struct safe_softc *sc = NULL;+	u32 mem_start, mem_len, cmd;+	int i, rc, devinfo;+	dma_addr_t raddr;+	static int num_chips = 0;++	DPRINTF(("%s()\n", __FUNCTION__));++	if (pci_enable_device(dev) < 0)+		return(-ENODEV);++	if (!dev->irq) {+		printk("safe: found device with no IRQ assigned. check BIOS settings!");+		pci_disable_device(dev);+		return(-ENODEV);+	}++	if (pci_set_mwi(dev)) {+		printk("safe: pci_set_mwi failed!");+		return(-ENODEV);+	}++	sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);+	if (!sc)+		return(-ENOMEM);+	memset(sc, 0, sizeof(*sc));++	softc_device_init(sc, "safe", num_chips, safe_methods);++	sc->sc_irq = -1;+	sc->sc_cid = -1;+	sc->sc_pcidev = dev;+	if (num_chips < SAFE_MAX_CHIPS) {+		safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;+		num_chips++;+	}++	INIT_LIST_HEAD(&sc->sc_pkq);+	spin_lock_init(&sc->sc_pkmtx);++	pci_set_drvdata(sc->sc_pcidev, sc);++	/* we read its hardware registers as memory */+	mem_start = pci_resource_start(sc->sc_pcidev, 0);+	mem_len   = pci_resource_len(sc->sc_pcidev, 0);++	sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);+	if (!sc->sc_base_addr) {+		device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",+				mem_start, mem_start + mem_len - 1);+		goto out;+	}++	/* fix up the bus size */+	if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {+		device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");+		goto out;+	}+	if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {+		device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");+		goto out;+	}++	pci_set_master(sc->sc_pcidev);++	pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);++	if (!(cmd & PCI_COMMAND_MEMORY)) {+		device_printf(sc->sc_dev, "failed to enable memory mapping\n");+		goto out;+	}++	if (!(cmd & PCI_COMMAND_MASTER)) {+		device_printf(sc->sc_dev, "failed to enable bus mastering\n");+		goto out;+	}++	rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);+	if (rc) {+		device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);+		goto out;+	}+	sc->sc_irq = dev->irq;++	sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &+			(SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);++	/*+	 * Allocate packet engine descriptors.+	 */+	sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,+			SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),+			&sc->sc_ringalloc.dma_paddr);+	if (!sc->sc_ringalloc.dma_vaddr) {+		device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");+		goto out;+	}++	/*+	 * Hookup the static portion of all our data structures.+	 */+	sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;+	sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;+	sc->sc_front = sc->sc_ring;+	sc->sc_back = sc->sc_ring;+	raddr = sc->sc_ringalloc.dma_paddr;+	bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));+	for (i = 0; i < SAFE_MAX_NQUEUE; i++) {+		struct safe_ringentry *re = &sc->sc_ring[i];++		re->re_desc.d_sa = raddr ++			offsetof(struct safe_ringentry, re_sa);+		re->re_sa.sa_staterec = raddr ++			offsetof(struct safe_ringentry, re_sastate);++		raddr += sizeof (struct safe_ringentry);+	}+	spin_lock_init(&sc->sc_ringmtx);++	/*+	 * Allocate scatter and gather particle descriptors.+	 */+	sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,+			SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),+			&sc->sc_spalloc.dma_paddr);+	if (!sc->sc_spalloc.dma_vaddr) {+		device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");+		goto out;+	}+	sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;+	sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;+	sc->sc_spfree = sc->sc_spring;+	bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));++	sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,+			SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),+			&sc->sc_dpalloc.dma_paddr);+	if (!sc->sc_dpalloc.dma_vaddr) {+		device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");+		goto out;+	}+	sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;+	sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;+	sc->sc_dpfree = sc->sc_dpring;+	bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));++	sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);+	if (sc->sc_cid < 0) {+		device_printf(sc->sc_dev, "could not get crypto driver id\n");+		goto out;+	}++	printf("%s:", device_get_nameunit(sc->sc_dev));++	devinfo = READ_REG(sc, SAFE_DEVINFO);+	if (devinfo & SAFE_DEVINFO_RNG) {+		sc->sc_flags |= SAFE_FLAGS_RNG;+		printf(" rng");+	}+	if (devinfo & SAFE_DEVINFO_PKEY) {+		printf(" key");+		sc->sc_flags |= SAFE_FLAGS_KEY;+		crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);+#if 0+		crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);+#endif+		init_timer(&sc->sc_pkto);+		sc->sc_pkto.function = safe_kpoll;+		sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);+	}+	if (devinfo & SAFE_DEVINFO_DES) {+		printf(" des/3des");+		crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);+	}+	if (devinfo & SAFE_DEVINFO_AES) {+		printf(" aes");+		crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);+	}+	if (devinfo & SAFE_DEVINFO_MD5) {+		printf(" md5");+		crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);+	}+	if (devinfo & SAFE_DEVINFO_SHA1) {+		printf(" sha1");+		crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);+	}+	printf(" null");+	crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);+	crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);+	/* XXX other supported algorithms */+	printf("\n");++	safe_reset_board(sc);		/* reset h/w */+	safe_init_board(sc);		/* init h/w */++#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)+	if (sc->sc_flags & SAFE_FLAGS_RNG) {+		safe_rng_init(sc);+		crypto_rregister(sc->sc_cid, safe_read_random, sc);+	}+#endif /* SAFE_NO_RNG */++	return (0);++out:+	if (sc->sc_cid >= 0)+		crypto_unregister_all(sc->sc_cid);+	if (sc->sc_irq != -1)+		free_irq(sc->sc_irq, sc);+	if (sc->sc_ringalloc.dma_vaddr)+		pci_free_consistent(sc->sc_pcidev,+				SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),+				sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);+	if (sc->sc_spalloc.dma_vaddr)+		pci_free_consistent(sc->sc_pcidev,+				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),+				sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);+	if (sc->sc_dpalloc.dma_vaddr)+		pci_free_consistent(sc->sc_pcidev,+				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),+				sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);+	kfree(sc);+	return(-ENODEV);+}++static void safe_remove(struct pci_dev *dev)+{+	struct safe_softc *sc = pci_get_drvdata(dev);++	DPRINTF(("%s()\n", __FUNCTION__));++	/* XXX wait/abort active ops */++	WRITE_REG(sc, SAFE_HI_MASK, 0);		/* disable interrupts */++	del_timer_sync(&sc->sc_pkto);++	crypto_unregister_all(sc->sc_cid);++	safe_cleanchip(sc);++	if (sc->sc_irq != -1)+		free_irq(sc->sc_irq, sc);+	if (sc->sc_ringalloc.dma_vaddr)+		pci_free_consistent(sc->sc_pcidev,+				SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),+				sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);+	if (sc->sc_spalloc.dma_vaddr)+		pci_free_consistent(sc->sc_pcidev,+				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),+				sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);+	if (sc->sc_dpalloc.dma_vaddr)+		pci_free_consistent(sc->sc_pcidev,+				SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),+				sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);+	sc->sc_irq = -1;+	sc->sc_ringalloc.dma_vaddr = NULL;+	sc->sc_spalloc.dma_vaddr = NULL;+	sc->sc_dpalloc.dma_vaddr = NULL;+}++static struct pci_device_id safe_pci_tbl[] = {+	{ PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },+	{ },+};+MODULE_DEVICE_TABLE(pci, safe_pci_tbl);++static struct pci_driver safe_driver = {+	.name         = "safe",+	.id_table     = safe_pci_tbl,+	.probe        =	safe_probe,+	.remove       = safe_remove,+	/* add PM stuff here one day */+};++static int __init safe_init (void)+{+	struct safe_softc *sc = NULL;+	int rc;++	DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));++	rc = pci_register_driver(&safe_driver);+	pci_register_driver_compat(&safe_driver, rc);++	return rc;+}++static void __exit safe_exit (void)+{+	pci_unregister_driver(&safe_driver);+}++module_init(safe_init);+module_exit(safe_exit);++MODULE_LICENSE("BSD");+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");+MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safereg.h linux-2.6.36/crypto/ocf/safe/safereg.h--- linux-2.6.36.orig/crypto/ocf/safe/safereg.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/safereg.h	2010-11-09 20:28:12.962495464 +0100@@ -0,0 +1,421 @@+/*-+ * Copyright (c) 2003 Sam Leffler, Errno Consulting+ * Copyright (c) 2003 Global Technology Associates, Inc.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ *+ * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $+ */+#ifndef _SAFE_SAFEREG_H_+#define	_SAFE_SAFEREG_H_++/*+ * Register definitions for SafeNet SafeXcel-1141 crypto device.+ * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.+ */++#define BS_BAR			0x10	/* DMA base address register */+#define	BS_TRDY_TIMEOUT		0x40	/* TRDY timeout */+#define	BS_RETRY_TIMEOUT	0x41	/* DMA retry timeout */++#define	PCI_VENDOR_SAFENET	0x16ae		/* SafeNet, Inc. */++/* SafeNet */+#define	PCI_PRODUCT_SAFEXCEL	0x1141		/* 1141 */++#define	SAFE_PE_CSR		0x0000	/* Packet Enginge Ctrl/Status */+#define	SAFE_PE_SRC		0x0004	/* Packet Engine Source */+#define	SAFE_PE_DST		0x0008	/* Packet Engine Destination */+#define	SAFE_PE_SA		0x000c	/* Packet Engine SA */+#define	SAFE_PE_LEN		0x0010	/* Packet Engine Length */+#define	SAFE_PE_DMACFG		0x0040	/* Packet Engine DMA Configuration */+#define	SAFE_PE_DMASTAT		0x0044	/* Packet Engine DMA Status */+#define	SAFE_PE_PDRBASE		0x0048	/* Packet Engine Descriptor Ring Base */+#define	SAFE_PE_RDRBASE		0x004c	/* Packet Engine Result Ring Base */+#define	SAFE_PE_RINGCFG		0x0050	/* Packet Engine Ring Configuration */+#define	SAFE_PE_RINGPOLL	0x0054	/* Packet Engine Ring Poll */+#define	SAFE_PE_IRNGSTAT	0x0058	/* Packet Engine Internal Ring Status */+#define	SAFE_PE_ERNGSTAT	0x005c	/* Packet Engine External Ring Status */+#define	SAFE_PE_IOTHRESH	0x0060	/* Packet Engine I/O Threshold */+#define	SAFE_PE_GRNGBASE	0x0064	/* Packet Engine Gather Ring Base */+#define	SAFE_PE_SRNGBASE	0x0068	/* Packet Engine Scatter Ring Base */+#define	SAFE_PE_PARTSIZE	0x006c	/* Packet Engine Particlar Ring Size */+#define	SAFE_PE_PARTCFG		0x0070	/* Packet Engine Particle Ring Config */+#define	SAFE_CRYPTO_CTRL	0x0080	/* Crypto Control */+#define	SAFE_DEVID		0x0084	/* Device ID */+#define	SAFE_DEVINFO		0x0088	/* Device Info */+#define	SAFE_HU_STAT		0x00a0	/* Host Unmasked Status */+#define	SAFE_HM_STAT		0x00a4	/* Host Masked Status (read-only) */+#define	SAFE_HI_CLR		0x00a4	/* Host Clear Interrupt (write-only) */+#define	SAFE_HI_MASK		0x00a8	/* Host Mask Control */+#define	SAFE_HI_CFG		0x00ac	/* Interrupt Configuration */+#define	SAFE_HI_RD_DESCR	0x00b4	/* Force Descriptor Read */+#define	SAFE_HI_DESC_CNT	0x00b8	/* Host Descriptor Done Count */+#define	SAFE_DMA_ENDIAN		0x00c0	/* Master Endian Status */+#define	SAFE_DMA_SRCADDR	0x00c4	/* DMA Source Address Status */+#define	SAFE_DMA_DSTADDR	0x00c8	/* DMA Destination Address Status */+#define	SAFE_DMA_STAT		0x00cc	/* DMA Current Status */+#define	SAFE_DMA_CFG		0x00d4	/* DMA Configuration/Status */+#define	SAFE_ENDIAN		0x00e0	/* Endian Configuration */+#define	SAFE_PK_A_ADDR		0x0800	/* Public Key A Address */+#define	SAFE_PK_B_ADDR		0x0804	/* Public Key B Address */+#define	SAFE_PK_C_ADDR		0x0808	/* Public Key C Address */+#define	SAFE_PK_D_ADDR		0x080c	/* Public Key D Address */+#define	SAFE_PK_A_LEN		0x0810	/* Public Key A Length */+#define	SAFE_PK_B_LEN		0x0814	/* Public Key B Length */+#define	SAFE_PK_SHIFT		0x0818	/* Public Key Shift */+#define	SAFE_PK_FUNC		0x081c	/* Public Key Function */+#define SAFE_PK_RAM_START	0x1000	/* Public Key RAM start address */+#define SAFE_PK_RAM_END		0x1fff	/* Public Key RAM end address */++#define	SAFE_RNG_OUT		0x0100	/* RNG Output */+#define	SAFE_RNG_STAT		0x0104	/* RNG Status */+#define	SAFE_RNG_CTRL		0x0108	/* RNG Control */+#define	SAFE_RNG_A		0x010c	/* RNG A */+#define	SAFE_RNG_B		0x0110	/* RNG B */+#define	SAFE_RNG_X_LO		0x0114	/* RNG X [31:0] */+#define	SAFE_RNG_X_MID		0x0118	/* RNG X [63:32] */+#define	SAFE_RNG_X_HI		0x011c	/* RNG X [80:64] */+#define	SAFE_RNG_X_CNTR		0x0120	/* RNG Counter */+#define	SAFE_RNG_ALM_CNT	0x0124	/* RNG Alarm Count */+#define	SAFE_RNG_CNFG		0x0128	/* RNG Configuration */+#define	SAFE_RNG_LFSR1_LO	0x012c	/* RNG LFSR1 [31:0] */+#define	SAFE_RNG_LFSR1_HI	0x0130	/* RNG LFSR1 [47:32] */+#define	SAFE_RNG_LFSR2_LO	0x0134	/* RNG LFSR1 [31:0] */+#define	SAFE_RNG_LFSR2_HI	0x0138	/* RNG LFSR1 [47:32] */++#define	SAFE_PE_CSR_READY	0x00000001	/* ready for processing */+#define	SAFE_PE_CSR_DONE	0x00000002	/* h/w completed processing */+#define	SAFE_PE_CSR_LOADSA	0x00000004	/* load SA digests */+#define	SAFE_PE_CSR_HASHFINAL	0x00000010	/* do hash pad & write result */+#define	SAFE_PE_CSR_SABUSID	0x000000c0	/* bus id for SA */+#define	SAFE_PE_CSR_SAPCI	0x00000040	/* PCI bus id for SA */+#define	SAFE_PE_CSR_NXTHDR	0x0000ff00	/* next hdr value for IPsec */+#define	SAFE_PE_CSR_FPAD	0x0000ff00	/* fixed pad for basic ops */+#define	SAFE_PE_CSR_STATUS	0x00ff0000	/* operation result status */+#define	SAFE_PE_CSR_AUTH_FAIL	0x00010000	/* ICV mismatch (inbound) */+#define	SAFE_PE_CSR_PAD_FAIL	0x00020000	/* pad verify fail (inbound) */+#define	SAFE_PE_CSR_SEQ_FAIL	0x00040000	/* sequence number (inbound) */+#define	SAFE_PE_CSR_XERROR	0x00080000	/* extended error follows */+#define	SAFE_PE_CSR_XECODE	0x00f00000	/* extended error code */+#define	SAFE_PE_CSR_XECODE_S	20+#define	SAFE_PE_CSR_XECODE_BADCMD	0	/* invalid command */+#define	SAFE_PE_CSR_XECODE_BADALG	1	/* invalid algorithm */+#define	SAFE_PE_CSR_XECODE_ALGDIS	2	/* algorithm disabled */+#define	SAFE_PE_CSR_XECODE_ZEROLEN	3	/* zero packet length */+#define	SAFE_PE_CSR_XECODE_DMAERR	4	/* bus DMA error */+#define	SAFE_PE_CSR_XECODE_PIPEABORT	5	/* secondary bus DMA error */+#define	SAFE_PE_CSR_XECODE_BADSPI	6	/* IPsec SPI mismatch */+#define	SAFE_PE_CSR_XECODE_TIMEOUT	10	/* failsafe timeout */+#define	SAFE_PE_CSR_PAD		0xff000000	/* ESP padding control/status */+#define	SAFE_PE_CSR_PAD_MIN	0x00000000	/* minimum IPsec padding */+#define	SAFE_PE_CSR_PAD_16	0x08000000	/* pad to 16-byte boundary */+#define	SAFE_PE_CSR_PAD_32	0x10000000	/* pad to 32-byte boundary */+#define	SAFE_PE_CSR_PAD_64	0x20000000	/* pad to 64-byte boundary */+#define	SAFE_PE_CSR_PAD_128	0x40000000	/* pad to 128-byte boundary */+#define	SAFE_PE_CSR_PAD_256	0x80000000	/* pad to 256-byte boundary */++/*+ * Check the CSR to see if the PE has returned ownership to+ * the host.  Note that before processing a descriptor this+ * must be done followed by a check of the SAFE_PE_LEN register+ * status bits to avoid premature processing of a descriptor+ * on its way back to the host.+ */+#define	SAFE_PE_CSR_IS_DONE(_csr) \+    (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)++#define	SAFE_PE_LEN_LENGTH	0x000fffff	/* total length (bytes) */+#define	SAFE_PE_LEN_READY	0x00400000	/* ready for processing */+#define	SAFE_PE_LEN_DONE	0x00800000	/* h/w completed processing */+#define	SAFE_PE_LEN_BYPASS	0xff000000	/* bypass offset (bytes) */+#define	SAFE_PE_LEN_BYPASS_S	24++#define	SAFE_PE_LEN_IS_DONE(_len) \+    (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)++/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */+#define	SAFE_INT_PE_CDONE	0x00000002	/* PE context done */+#define	SAFE_INT_PE_DDONE	0x00000008	/* PE descriptor done */+#define	SAFE_INT_PE_ERROR	0x00000010	/* PE error */+#define	SAFE_INT_PE_ODONE	0x00000020	/* PE operation done */++#define	SAFE_HI_CFG_PULSE	0x00000001	/* use pulse interrupt */+#define	SAFE_HI_CFG_LEVEL	0x00000000	/* use level interrupt */+#define	SAFE_HI_CFG_AUTOCLR	0x00000002	/* auto-clear pulse interrupt */++#define	SAFE_ENDIAN_PASS	0x000000e4	/* straight pass-thru */+#define	SAFE_ENDIAN_SWAB	0x0000001b	/* swap bytes in 32-bit word */++#define	SAFE_PE_DMACFG_PERESET	0x00000001	/* reset packet engine */+#define	SAFE_PE_DMACFG_PDRRESET	0x00000002	/* reset PDR counters/ptrs */+#define	SAFE_PE_DMACFG_SGRESET	0x00000004	/* reset scatter/gather cache */+#define	SAFE_PE_DMACFG_FSENA	0x00000008	/* enable failsafe reset */+#define	SAFE_PE_DMACFG_PEMODE	0x00000100	/* packet engine mode */+#define	SAFE_PE_DMACFG_SAPREC	0x00000200	/* SA precedes packet */+#define	SAFE_PE_DMACFG_PKFOLL	0x00000400	/* packet follows descriptor */+#define	SAFE_PE_DMACFG_GPRBID	0x00003000	/* gather particle ring busid */+#define	SAFE_PE_DMACFG_GPRPCI	0x00001000	/* PCI gather particle ring */+#define	SAFE_PE_DMACFG_SPRBID	0x0000c000	/* scatter part. ring busid */+#define	SAFE_PE_DMACFG_SPRPCI	0x00004000	/* PCI scatter part. ring */+#define	SAFE_PE_DMACFG_ESDESC	0x00010000	/* endian swap descriptors */+#define	SAFE_PE_DMACFG_ESSA	0x00020000	/* endian swap SA data */+#define	SAFE_PE_DMACFG_ESPACKET	0x00040000	/* endian swap packet data */+#define	SAFE_PE_DMACFG_ESPDESC	0x00080000	/* endian swap particle desc. */+#define	SAFE_PE_DMACFG_NOPDRUP	0x00100000	/* supp. PDR ownership update */+#define	SAFE_PD_EDMACFG_PCIMODE	0x01000000	/* PCI target mode */++#define	SAFE_PE_DMASTAT_PEIDONE	0x00000001	/* PE core input done */+#define	SAFE_PE_DMASTAT_PEODONE	0x00000002	/* PE core output done */+#define	SAFE_PE_DMASTAT_ENCDONE	0x00000004	/* encryption done */+#define	SAFE_PE_DMASTAT_IHDONE	0x00000008	/* inner hash done */+#define	SAFE_PE_DMASTAT_OHDONE	0x00000010	/* outer hash (HMAC) done */+#define	SAFE_PE_DMASTAT_PADFLT	0x00000020	/* crypto pad fault */+#define	SAFE_PE_DMASTAT_ICVFLT	0x00000040	/* ICV fault */+#define	SAFE_PE_DMASTAT_SPIMIS	0x00000080	/* SPI mismatch */+#define	SAFE_PE_DMASTAT_CRYPTO	0x00000100	/* crypto engine timeout */+#define	SAFE_PE_DMASTAT_CQACT	0x00000200	/* command queue active */+#define	SAFE_PE_DMASTAT_IRACT	0x00000400	/* input request active */+#define	SAFE_PE_DMASTAT_ORACT	0x00000800	/* output request active */+#define	SAFE_PE_DMASTAT_PEISIZE	0x003ff000	/* PE input size:32-bit words */+#define	SAFE_PE_DMASTAT_PEOSIZE	0xffc00000	/* PE out. size:32-bit words */++#define	SAFE_PE_RINGCFG_SIZE	0x000003ff	/* ring size (descriptors) */+#define	SAFE_PE_RINGCFG_OFFSET	0xffff0000	/* offset btw desc's (dwords) */+#define	SAFE_PE_RINGCFG_OFFSET_S	16++#define	SAFE_PE_RINGPOLL_POLL	0x00000fff	/* polling frequency/divisor */+#define	SAFE_PE_RINGPOLL_RETRY	0x03ff0000	/* polling frequency/divisor */+#define	SAFE_PE_RINGPOLL_CONT	0x80000000	/* continuously poll */++#define	SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001	/* command queue available */++#define	SAFE_PE_ERNGSTAT_NEXT	0x03ff0000	/* index of next packet desc. */+#define	SAFE_PE_ERNGSTAT_NEXT_S	16++#define	SAFE_PE_IOTHRESH_INPUT	0x000003ff	/* input threshold (dwords) */+#define	SAFE_PE_IOTHRESH_OUTPUT	0x03ff0000	/* output threshold (dwords) */++#define	SAFE_PE_PARTCFG_SIZE	0x0000ffff	/* scatter particle size */+#define	SAFE_PE_PARTCFG_GBURST	0x00030000	/* gather particle burst */+#define	SAFE_PE_PARTCFG_GBURST_2	0x00000000+#define	SAFE_PE_PARTCFG_GBURST_4	0x00010000+#define	SAFE_PE_PARTCFG_GBURST_8	0x00020000+#define	SAFE_PE_PARTCFG_GBURST_16	0x00030000+#define	SAFE_PE_PARTCFG_SBURST	0x000c0000	/* scatter particle burst */+#define	SAFE_PE_PARTCFG_SBURST_2	0x00000000+#define	SAFE_PE_PARTCFG_SBURST_4	0x00040000+#define	SAFE_PE_PARTCFG_SBURST_8	0x00080000+#define	SAFE_PE_PARTCFG_SBURST_16	0x000c0000++#define	SAFE_PE_PARTSIZE_SCAT	0xffff0000	/* scatter particle ring size */+#define	SAFE_PE_PARTSIZE_GATH	0x0000ffff	/* gather particle ring size */++#define	SAFE_CRYPTO_CTRL_3DES	0x00000001	/* enable 3DES support */+#define	SAFE_CRYPTO_CTRL_PKEY	0x00010000	/* enable public key support */+#define	SAFE_CRYPTO_CTRL_RNG	0x00020000	/* enable RNG support */++#define	SAFE_DEVINFO_REV_MIN	0x0000000f	/* minor rev for chip */+#define	SAFE_DEVINFO_REV_MAJ	0x000000f0	/* major rev for chip */+#define	SAFE_DEVINFO_REV_MAJ_S	4+#define	SAFE_DEVINFO_DES	0x00000100	/* DES/3DES support present */+#define	SAFE_DEVINFO_ARC4	0x00000200	/* ARC4 support present */+#define	SAFE_DEVINFO_AES	0x00000400	/* AES support present */+#define	SAFE_DEVINFO_MD5	0x00001000	/* MD5 support present */+#define	SAFE_DEVINFO_SHA1	0x00002000	/* SHA-1 support present */+#define	SAFE_DEVINFO_RIPEMD	0x00004000	/* RIPEMD support present */+#define	SAFE_DEVINFO_DEFLATE	0x00010000	/* Deflate support present */+#define	SAFE_DEVINFO_SARAM	0x00100000	/* on-chip SA RAM present */+#define	SAFE_DEVINFO_EMIBUS	0x00200000	/* EMI bus present */+#define	SAFE_DEVINFO_PKEY	0x00400000	/* public key support present */+#define	SAFE_DEVINFO_RNG	0x00800000	/* RNG present */++#define	SAFE_REV(_maj, _min)	(((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))+#define	SAFE_REV_MAJ(_chiprev) \+	(((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)+#define	SAFE_REV_MIN(_chiprev)	((_chiprev) & SAFE_DEVINFO_REV_MIN)++#define	SAFE_PK_FUNC_MULT	0x00000001	/* Multiply function */+#define	SAFE_PK_FUNC_SQUARE	0x00000004	/* Square function */+#define	SAFE_PK_FUNC_ADD	0x00000010	/* Add function */+#define	SAFE_PK_FUNC_SUB	0x00000020	/* Subtract function */+#define	SAFE_PK_FUNC_LSHIFT	0x00000040	/* Left-shift function */+#define	SAFE_PK_FUNC_RSHIFT	0x00000080	/* Right-shift function */+#define	SAFE_PK_FUNC_DIV	0x00000100	/* Divide function */+#define	SAFE_PK_FUNC_CMP	0x00000400	/* Compare function */+#define	SAFE_PK_FUNC_COPY	0x00000800	/* Copy function */+#define	SAFE_PK_FUNC_EXP16	0x00002000	/* Exponentiate (4-bit ACT) */+#define	SAFE_PK_FUNC_EXP4	0x00004000	/* Exponentiate (2-bit ACT) */+#define	SAFE_PK_FUNC_RUN	0x00008000	/* start/status */++#define	SAFE_RNG_STAT_BUSY	0x00000001	/* busy, data not valid */++#define	SAFE_RNG_CTRL_PRE_LFSR	0x00000001	/* enable output pre-LFSR */+#define	SAFE_RNG_CTRL_TST_MODE	0x00000002	/* enable test mode */+#define	SAFE_RNG_CTRL_TST_RUN	0x00000004	/* start test state machine */+#define	SAFE_RNG_CTRL_ENA_RING1	0x00000008	/* test entropy oscillator #1 */+#define	SAFE_RNG_CTRL_ENA_RING2	0x00000010	/* test entropy oscillator #2 */+#define	SAFE_RNG_CTRL_DIS_ALARM	0x00000020	/* disable RNG alarm reports */+#define	SAFE_RNG_CTRL_TST_CLOCK	0x00000040	/* enable test clock */+#define	SAFE_RNG_CTRL_SHORTEN	0x00000080	/* shorten state timers */+#define	SAFE_RNG_CTRL_TST_ALARM	0x00000100	/* simulate alarm state */+#define	SAFE_RNG_CTRL_RST_LFSR	0x00000200	/* reset LFSR */++/*+ * Packet engine descriptor.  Note that d_csr is a copy of the+ * SAFE_PE_CSR register and all definitions apply, and d_len+ * is a copy of the SAFE_PE_LEN register and all definitions apply.+ * d_src and d_len may point directly to contiguous data or to a+ * list of ``particle descriptors'' when using scatter/gather i/o.+ */+struct safe_desc {+	u_int32_t	d_csr;			/* per-packet control/status */+	u_int32_t	d_src;			/* source address */+	u_int32_t	d_dst;			/* destination address */+	u_int32_t	d_sa;			/* SA address */+	u_int32_t	d_len;			/* length, bypass, status */+};++/*+ * Scatter/Gather particle descriptor.+ *+ * NB: scatter descriptors do not specify a size; this is fixed+ *     by the setting of the SAFE_PE_PARTCFG register.+ */+struct safe_pdesc {+	u_int32_t	pd_addr;		/* particle address */+#ifdef __BIG_ENDIAN+	u_int16_t	pd_flags;		/* control word */+	u_int16_t	pd_size;		/* particle size (bytes) */+#else+	u_int16_t	pd_flags;		/* control word */+	u_int16_t	pd_size;		/* particle size (bytes) */+#endif+};++#define	SAFE_PD_READY	0x0001			/* ready for processing */+#define	SAFE_PD_DONE	0x0002			/* h/w completed processing */++/*+ * Security Association (SA) Record (Rev 1).  One of these is+ * required for each operation processed by the packet engine.+ */+struct safe_sarec {+	u_int32_t	sa_cmd0;+	u_int32_t	sa_cmd1;+	u_int32_t	sa_resv0;+	u_int32_t	sa_resv1;+	u_int32_t	sa_key[8];		/* DES/3DES/AES key */+	u_int32_t	sa_indigest[5];		/* inner digest */+	u_int32_t	sa_outdigest[5];	/* outer digest */+	u_int32_t	sa_spi;			/* SPI */+	u_int32_t	sa_seqnum;		/* sequence number */+	u_int32_t	sa_seqmask[2];		/* sequence number mask */+	u_int32_t	sa_resv2;+	u_int32_t	sa_staterec;		/* address of state record */+	u_int32_t	sa_resv3[2];+	u_int32_t	sa_samgmt0;		/* SA management field 0 */+	u_int32_t	sa_samgmt1;		/* SA management field 0 */+};++#define	SAFE_SA_CMD0_OP		0x00000007	/* operation code */+#define	SAFE_SA_CMD0_OP_CRYPT	0x00000000	/* encrypt/decrypt (basic) */+#define	SAFE_SA_CMD0_OP_BOTH	0x00000001	/* encrypt-hash/hash-decrypto */+#define	SAFE_SA_CMD0_OP_HASH	0x00000003	/* hash (outbound-only) */+#define	SAFE_SA_CMD0_OP_ESP	0x00000000	/* ESP in/out (proto) */+#define	SAFE_SA_CMD0_OP_AH	0x00000001	/* AH in/out (proto) */+#define	SAFE_SA_CMD0_INBOUND	0x00000008	/* inbound operation */+#define	SAFE_SA_CMD0_OUTBOUND	0x00000000	/* outbound operation */+#define	SAFE_SA_CMD0_GROUP	0x00000030	/* operation group */+#define	SAFE_SA_CMD0_BASIC	0x00000000	/* basic operation */+#define	SAFE_SA_CMD0_PROTO	0x00000010	/* protocol/packet operation */+#define	SAFE_SA_CMD0_BUNDLE	0x00000020	/* bundled operation (resvd) */+#define	SAFE_SA_CMD0_PAD	0x000000c0	/* crypto pad method */+#define	SAFE_SA_CMD0_PAD_IPSEC	0x00000000	/* IPsec padding */+#define	SAFE_SA_CMD0_PAD_PKCS7	0x00000040	/* PKCS#7 padding */+#define	SAFE_SA_CMD0_PAD_CONS	0x00000080	/* constant padding */+#define	SAFE_SA_CMD0_PAD_ZERO	0x000000c0	/* zero padding */+#define	SAFE_SA_CMD0_CRYPT_ALG	0x00000f00	/* symmetric crypto algorithm */+#define	SAFE_SA_CMD0_DES	0x00000000	/* DES crypto algorithm */+#define	SAFE_SA_CMD0_3DES	0x00000100	/* 3DES crypto algorithm */+#define	SAFE_SA_CMD0_AES	0x00000300	/* AES crypto algorithm */+#define	SAFE_SA_CMD0_CRYPT_NULL	0x00000f00	/* null crypto algorithm */+#define	SAFE_SA_CMD0_HASH_ALG	0x0000f000	/* hash algorithm */+#define	SAFE_SA_CMD0_MD5	0x00000000	/* MD5 hash algorithm */+#define	SAFE_SA_CMD0_SHA1	0x00001000	/* SHA-1 hash algorithm */+#define	SAFE_SA_CMD0_HASH_NULL	0x0000f000	/* null hash algorithm */+#define	SAFE_SA_CMD0_HDR_PROC	0x00080000	/* header processing */+#define	SAFE_SA_CMD0_IBUSID	0x00300000	/* input bus id */+#define	SAFE_SA_CMD0_IPCI	0x00100000	/* PCI input bus id */+#define	SAFE_SA_CMD0_OBUSID	0x00c00000	/* output bus id */+#define	SAFE_SA_CMD0_OPCI	0x00400000	/* PCI output bus id */+#define	SAFE_SA_CMD0_IVLD	0x03000000	/* IV loading */+#define	SAFE_SA_CMD0_IVLD_NONE	0x00000000	/* IV no load (reuse) */+#define	SAFE_SA_CMD0_IVLD_IBUF	0x01000000	/* IV load from input buffer */+#define	SAFE_SA_CMD0_IVLD_STATE	0x02000000	/* IV load from state */+#define	SAFE_SA_CMD0_HSLD	0x0c000000	/* hash state loading */+#define	SAFE_SA_CMD0_HSLD_SA	0x00000000	/* hash state load from SA */+#define	SAFE_SA_CMD0_HSLD_STATE	0x08000000	/* hash state load from state */+#define	SAFE_SA_CMD0_HSLD_NONE	0x0c000000	/* hash state no load */+#define	SAFE_SA_CMD0_SAVEIV	0x10000000	/* save IV */+#define	SAFE_SA_CMD0_SAVEHASH	0x20000000	/* save hash state */+#define	SAFE_SA_CMD0_IGATHER	0x40000000	/* input gather */+#define	SAFE_SA_CMD0_OSCATTER	0x80000000	/* output scatter */++#define	SAFE_SA_CMD1_HDRCOPY	0x00000002	/* copy header to output */+#define	SAFE_SA_CMD1_PAYCOPY	0x00000004	/* copy payload to output */+#define	SAFE_SA_CMD1_PADCOPY	0x00000008	/* copy pad to output */+#define	SAFE_SA_CMD1_IPV4	0x00000000	/* IPv4 protocol */+#define	SAFE_SA_CMD1_IPV6	0x00000010	/* IPv6 protocol */+#define	SAFE_SA_CMD1_MUTABLE	0x00000020	/* mutable bit processing */+#define	SAFE_SA_CMD1_SRBUSID	0x000000c0	/* state record bus id */+#define	SAFE_SA_CMD1_SRPCI	0x00000040	/* state record from PCI */+#define	SAFE_SA_CMD1_CRMODE	0x00000300	/* crypto mode */+#define	SAFE_SA_CMD1_ECB	0x00000000	/* ECB crypto mode */+#define	SAFE_SA_CMD1_CBC	0x00000100	/* CBC crypto mode */+#define	SAFE_SA_CMD1_OFB	0x00000200	/* OFB crypto mode */+#define	SAFE_SA_CMD1_CFB	0x00000300	/* CFB crypto mode */+#define	SAFE_SA_CMD1_CRFEEDBACK	0x00000c00	/* crypto feedback mode */+#define	SAFE_SA_CMD1_64BIT	0x00000000	/* 64-bit crypto feedback */+#define	SAFE_SA_CMD1_8BIT	0x00000400	/* 8-bit crypto feedback */+#define	SAFE_SA_CMD1_1BIT	0x00000800	/* 1-bit crypto feedback */+#define	SAFE_SA_CMD1_128BIT	0x00000c00	/* 128-bit crypto feedback */+#define	SAFE_SA_CMD1_OPTIONS	0x00001000	/* HMAC/options mutable bit */+#define	SAFE_SA_CMD1_HMAC	SAFE_SA_CMD1_OPTIONS+#define	SAFE_SA_CMD1_SAREV1	0x00008000	/* SA Revision 1 */+#define	SAFE_SA_CMD1_OFFSET	0x00ff0000	/* hash/crypto offset(dwords) */+#define	SAFE_SA_CMD1_OFFSET_S	16+#define	SAFE_SA_CMD1_AESKEYLEN	0x0f000000	/* AES key length */+#define	SAFE_SA_CMD1_AES128	0x02000000	/* 128-bit AES key */+#define	SAFE_SA_CMD1_AES192	0x03000000	/* 192-bit AES key */+#define	SAFE_SA_CMD1_AES256	0x04000000	/* 256-bit AES key */++/* + * Security Associate State Record (Rev 1).+ */+struct safe_sastate {+	u_int32_t	sa_saved_iv[4];		/* saved IV (DES/3DES/AES) */+	u_int32_t	sa_saved_hashbc;	/* saved hash byte count */+	u_int32_t	sa_saved_indigest[5];	/* saved inner digest */+};+#endif /* _SAFE_SAFEREG_H_ */diff -Nur linux-2.6.36.orig/crypto/ocf/safe/safevar.h linux-2.6.36/crypto/ocf/safe/safevar.h--- linux-2.6.36.orig/crypto/ocf/safe/safevar.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/safevar.h	2010-11-09 20:28:13.022495375 +0100@@ -0,0 +1,230 @@+/*-+ * The linux port of this code done by David McCullough+ * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>+ * The license and original author are listed below.+ *+ * Copyright (c) 2003 Sam Leffler, Errno Consulting+ * Copyright (c) 2003 Global Technology Associates, Inc.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ *+ * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $+ */+#ifndef _SAFE_SAFEVAR_H_+#define	_SAFE_SAFEVAR_H_++/* Maximum queue length */+#ifndef SAFE_MAX_NQUEUE+#define SAFE_MAX_NQUEUE	60+#endif++#define	SAFE_MAX_PART		64	/* Maximum scatter/gather depth */+#define	SAFE_DMA_BOUNDARY	0	/* No boundary for source DMA ops */+#define	SAFE_MAX_DSIZE		2048 /* MCLBYTES Fixed scatter particle size */+#define	SAFE_MAX_SSIZE		0x0ffff	/* Maximum gather particle size */+#define	SAFE_MAX_DMA		0xfffff	/* Maximum PE operand size (20 bits) */+/* total src+dst particle descriptors */+#define	SAFE_TOTAL_DPART	(SAFE_MAX_NQUEUE * SAFE_MAX_PART)+#define	SAFE_TOTAL_SPART	(SAFE_MAX_NQUEUE * SAFE_MAX_PART)++#define	SAFE_RNG_MAXBUFSIZ	128	/* 32-bit words */++#define	SAFE_CARD(sid)		(((sid) & 0xf0000000) >> 28)+#define	SAFE_SESSION(sid)	( (sid) & 0x0fffffff)+#define	SAFE_SID(crd, sesn)	(((crd) << 28) | ((sesn) & 0x0fffffff))++#define SAFE_DEF_RTY		0xff	/* PCI Retry Timeout */+#define SAFE_DEF_TOUT		0xff	/* PCI TRDY Timeout */+#define SAFE_DEF_CACHELINE	0x01	/* Cache Line setting */++#ifdef __KERNEL__+/*+ * State associated with the allocation of each chunk+ * of memory setup for DMA.+ */+struct safe_dma_alloc {+	dma_addr_t		dma_paddr;+	void			*dma_vaddr;+};++/*+ * Cryptographic operand state.  One of these exists for each+ * source and destination operand passed in from the crypto+ * subsystem.  When possible source and destination operands+ * refer to the same memory.  More often they are distinct.+ * We track the virtual address of each operand as well as+ * where each is mapped for DMA.+ */+struct safe_operand {+	union {+		struct sk_buff *skb;+		struct uio *io;+	} u;+	void			*map;+	int				mapsize;	/* total number of bytes in segs */+	struct {+		dma_addr_t	ds_addr;+		int			ds_len;+		int			ds_tlen;+	} segs[SAFE_MAX_PART];+	int				nsegs;+};++/*+ * Packet engine ring entry and cryptographic operation state.+ * The packet engine requires a ring of descriptors that contain+ * pointers to various cryptographic state.  However the ring+ * configuration register allows you to specify an arbitrary size+ * for ring entries.  We use this feature to collect most of the+ * state for each cryptographic request into one spot.  Other than+ * ring entries only the ``particle descriptors'' (scatter/gather+ * lists) and the actual operand data are kept separate.  The+ * particle descriptors must also be organized in rings.  The+ * operand data can be located aribtrarily (modulo alignment constraints).+ *+ * Note that the descriptor ring is mapped onto the PCI bus so+ * the hardware can DMA data.  This means the entire ring must be+ * contiguous.+ */+struct safe_ringentry {+	struct safe_desc	re_desc;	/* command descriptor */+	struct safe_sarec	re_sa;		/* SA record */+	struct safe_sastate	re_sastate;	/* SA state record */++	struct cryptop		*re_crp;	/* crypto operation */++	struct safe_operand	re_src;		/* source operand */+	struct safe_operand	re_dst;		/* destination operand */++	int			re_sesn;	/* crypto session ID */+	int			re_flags;+#define	SAFE_QFLAGS_COPYOUTIV	0x1		/* copy back on completion */+#define	SAFE_QFLAGS_COPYOUTICV	0x2		/* copy back on completion */+};++#define	re_src_skb	re_src.u.skb+#define	re_src_io	re_src.u.io+#define	re_src_map	re_src.map+#define	re_src_nsegs	re_src.nsegs+#define	re_src_segs	re_src.segs+#define	re_src_mapsize	re_src.mapsize++#define	re_dst_skb	re_dst.u.skb+#define	re_dst_io	re_dst.u.io+#define	re_dst_map	re_dst.map+#define	re_dst_nsegs	re_dst.nsegs+#define	re_dst_segs	re_dst.segs+#define	re_dst_mapsize	re_dst.mapsize++struct rndstate_test;++struct safe_session {+	u_int32_t	ses_used;+	u_int32_t	ses_klen;		/* key length in bits */+	u_int32_t	ses_key[8];		/* DES/3DES/AES key */+	u_int32_t	ses_mlen;		/* hmac length in bytes */+	u_int32_t	ses_hminner[5];		/* hmac inner state */+	u_int32_t	ses_hmouter[5];		/* hmac outer state */+	u_int32_t	ses_iv[4];		/* DES/3DES/AES iv */+};++struct safe_pkq {+	struct list_head	pkq_list;+	struct cryptkop		*pkq_krp;+};++struct safe_softc {+	softc_device_decl	sc_dev;+	u32			sc_irq;++	struct pci_dev		*sc_pcidev;+	ocf_iomem_t		sc_base_addr;++	u_int			sc_chiprev;	/* major/minor chip revision */+	int			sc_flags;	/* device specific flags */+#define	SAFE_FLAGS_KEY		0x01		/* has key accelerator */+#define	SAFE_FLAGS_RNG		0x02		/* hardware rng */+	int			sc_suspended;+	int			sc_needwakeup;	/* notify crypto layer */+	int32_t			sc_cid;		/* crypto tag */++	struct safe_dma_alloc	sc_ringalloc;	/* PE ring allocation state */+	struct safe_ringentry	*sc_ring;	/* PE ring */+	struct safe_ringentry	*sc_ringtop;	/* PE ring top */+	struct safe_ringentry	*sc_front;	/* next free entry */+	struct safe_ringentry	*sc_back;	/* next pending entry */+	int			sc_nqchip;	/* # passed to chip */+	spinlock_t		sc_ringmtx;	/* PE ring lock */+	struct safe_pdesc	*sc_spring;	/* src particle ring */+	struct safe_pdesc	*sc_springtop;	/* src particle ring top */+	struct safe_pdesc	*sc_spfree;	/* next free src particle */+	struct safe_dma_alloc	sc_spalloc;	/* src particle ring state */+	struct safe_pdesc	*sc_dpring;	/* dest particle ring */+	struct safe_pdesc	*sc_dpringtop;	/* dest particle ring top */+	struct safe_pdesc	*sc_dpfree;	/* next free dest particle */+	struct safe_dma_alloc	sc_dpalloc;	/* dst particle ring state */+	int			sc_nsessions;	/* # of sessions */+	struct safe_session	*sc_sessions;	/* sessions */++	struct timer_list	sc_pkto;	/* PK polling */+	spinlock_t		sc_pkmtx;	/* PK lock */+	struct list_head	sc_pkq;		/* queue of PK requests */+	struct safe_pkq		*sc_pkq_cur;	/* current processing request */+	u_int32_t		sc_pk_reslen, sc_pk_resoff;++	int			sc_max_dsize;	/* maximum safe DMA size */+};+#endif /* __KERNEL__ */++struct safe_stats {+	u_int64_t st_ibytes;+	u_int64_t st_obytes;+	u_int32_t st_ipackets;+	u_int32_t st_opackets;+	u_int32_t st_invalid;		/* invalid argument */+	u_int32_t st_badsession;	/* invalid session id */+	u_int32_t st_badflags;		/* flags indicate !(mbuf | uio) */+	u_int32_t st_nodesc;		/* op submitted w/o descriptors */+	u_int32_t st_badalg;		/* unsupported algorithm */+	u_int32_t st_ringfull;		/* PE descriptor ring full */+	u_int32_t st_peoperr;		/* PE marked error */+	u_int32_t st_dmaerr;		/* PE DMA error */+	u_int32_t st_bypasstoobig;	/* bypass > 96 bytes */+	u_int32_t st_skipmismatch;	/* enc part begins before auth part */+	u_int32_t st_lenmismatch;	/* enc length different auth length */+	u_int32_t st_coffmisaligned;	/* crypto offset not 32-bit aligned */+	u_int32_t st_cofftoobig;	/* crypto offset > 255 words */+	u_int32_t st_iovmisaligned;	/* iov op not aligned */+	u_int32_t st_iovnotuniform;	/* iov op not suitable */+	u_int32_t st_unaligned;		/* unaligned src caused copy */+	u_int32_t st_notuniform;	/* non-uniform src caused copy */+	u_int32_t st_nomap;		/* bus_dmamap_create failed */+	u_int32_t st_noload;		/* bus_dmamap_load_* failed */+	u_int32_t st_nombuf;		/* MGET* failed */+	u_int32_t st_nomcl;		/* MCLGET* failed */+	u_int32_t st_maxqchip;		/* max mcr1 ops out for processing */+	u_int32_t st_rng;		/* RNG requests */+	u_int32_t st_rngalarm;		/* RNG alarm requests */+	u_int32_t st_noicvcopy;		/* ICV data copies suppressed */+};+#endif /* _SAFE_SAFEVAR_H_ */diff -Nur linux-2.6.36.orig/crypto/ocf/safe/sha1.c linux-2.6.36/crypto/ocf/safe/sha1.c--- linux-2.6.36.orig/crypto/ocf/safe/sha1.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/sha1.c	2010-11-09 20:28:13.072495484 +0100@@ -0,0 +1,279 @@+/*	$KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $	*/+/*+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the project nor the names of its contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++/*+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)+ * based on: http://csrc.nist.gov/fips/fip180-1.txt+ * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>+ */++#if 0+#include <sys/cdefs.h>+__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");++#include <sys/types.h>+#include <sys/cdefs.h>+#include <sys/time.h>+#include <sys/systm.h>++#include <crypto/sha1.h>+#endif++/* sanity check */+#if BYTE_ORDER != BIG_ENDIAN+# if BYTE_ORDER != LITTLE_ENDIAN+#  define unsupported 1+# endif+#endif++#ifndef unsupported++/* constant table */+static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };+#define	K(t)	_K[(t) / 20]++#define	F0(b, c, d)	(((b) & (c)) | ((~(b)) & (d)))+#define	F1(b, c, d)	(((b) ^ (c)) ^ (d))+#define	F2(b, c, d)	(((b) & (c)) | ((b) & (d)) | ((c) & (d)))+#define	F3(b, c, d)	(((b) ^ (c)) ^ (d))++#define	S(n, x)		(((x) << (n)) | ((x) >> (32 - n)))++#undef H+#define	H(n)	(ctxt->h.b32[(n)])+#define	COUNT	(ctxt->count)+#define	BCOUNT	(ctxt->c.b64[0] / 8)+#define	W(n)	(ctxt->m.b32[(n)])++#define	PUTBYTE(x)	{ \+	ctxt->m.b8[(COUNT % 64)] = (x);		\+	COUNT++;				\+	COUNT %= 64;				\+	ctxt->c.b64[0] += 8;			\+	if (COUNT % 64 == 0)			\+		sha1_step(ctxt);		\+     }++#define	PUTPAD(x)	{ \+	ctxt->m.b8[(COUNT % 64)] = (x);		\+	COUNT++;				\+	COUNT %= 64;				\+	if (COUNT % 64 == 0)			\+		sha1_step(ctxt);		\+     }++static void sha1_step(struct sha1_ctxt *);++static void+sha1_step(ctxt)+	struct sha1_ctxt *ctxt;+{+	u_int32_t	a, b, c, d, e;+	size_t t, s;+	u_int32_t	tmp;++#if BYTE_ORDER == LITTLE_ENDIAN+	struct sha1_ctxt tctxt;+	bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);+	ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];+	ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];+	ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];+	ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];+	ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];+	ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];+	ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];+	ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];+	ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];+	ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];+	ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];+	ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];+	ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];+	ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];+	ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];+	ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];+	ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];+	ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];+	ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];+	ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];+	ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];+	ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];+	ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];+	ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];+	ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];+	ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];+	ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];+	ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];+	ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];+	ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];+	ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];+	ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];+#endif++	a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);++	for (t = 0; t < 20; t++) {+		s = t & 0x0f;+		if (t >= 16) {+			W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));+		}+		tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);+		e = d; d = c; c = S(30, b); b = a; a = tmp;+	}+	for (t = 20; t < 40; t++) {+		s = t & 0x0f;+		W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));+		tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);+		e = d; d = c; c = S(30, b); b = a; a = tmp;+	}+	for (t = 40; t < 60; t++) {+		s = t & 0x0f;+		W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));+		tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);+		e = d; d = c; c = S(30, b); b = a; a = tmp;+	}+	for (t = 60; t < 80; t++) {+		s = t & 0x0f;+		W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));+		tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);+		e = d; d = c; c = S(30, b); b = a; a = tmp;+	}++	H(0) = H(0) + a;+	H(1) = H(1) + b;+	H(2) = H(2) + c;+	H(3) = H(3) + d;+	H(4) = H(4) + e;++	bzero(&ctxt->m.b8[0], 64);+}++/*------------------------------------------------------------*/++void+sha1_init(ctxt)+	struct sha1_ctxt *ctxt;+{+	bzero(ctxt, sizeof(struct sha1_ctxt));+	H(0) = 0x67452301;+	H(1) = 0xefcdab89;+	H(2) = 0x98badcfe;+	H(3) = 0x10325476;+	H(4) = 0xc3d2e1f0;+}++void+sha1_pad(ctxt)+	struct sha1_ctxt *ctxt;+{+	size_t padlen;		/*pad length in bytes*/+	size_t padstart;++	PUTPAD(0x80);++	padstart = COUNT % 64;+	padlen = 64 - padstart;+	if (padlen < 8) {+		bzero(&ctxt->m.b8[padstart], padlen);+		COUNT += padlen;+		COUNT %= 64;+		sha1_step(ctxt);+		padstart = COUNT % 64;	/* should be 0 */+		padlen = 64 - padstart;	/* should be 64 */+	}+	bzero(&ctxt->m.b8[padstart], padlen - 8);+	COUNT += (padlen - 8);+	COUNT %= 64;+#if BYTE_ORDER == BIG_ENDIAN+	PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);+	PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);+	PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);+	PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);+#else+	PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);+	PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);+	PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);+	PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);+#endif+}++void+sha1_loop(ctxt, input, len)+	struct sha1_ctxt *ctxt;+	const u_int8_t *input;+	size_t len;+{+	size_t gaplen;+	size_t gapstart;+	size_t off;+	size_t copysiz;++	off = 0;++	while (off < len) {+		gapstart = COUNT % 64;+		gaplen = 64 - gapstart;++		copysiz = (gaplen < len - off) ? gaplen : len - off;+		bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);+		COUNT += copysiz;+		COUNT %= 64;+		ctxt->c.b64[0] += copysiz * 8;+		if (COUNT % 64 == 0)+			sha1_step(ctxt);+		off += copysiz;+	}+}++void+sha1_result(ctxt, digest0)+	struct sha1_ctxt *ctxt;+	caddr_t digest0;+{+	u_int8_t *digest;++	digest = (u_int8_t *)digest0;+	sha1_pad(ctxt);+#if BYTE_ORDER == BIG_ENDIAN+	bcopy(&ctxt->h.b8[0], digest, 20);+#else+	digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];+	digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];+	digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];+	digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];+	digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];+	digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];+	digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];+	digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];+	digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];+	digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];+#endif+}++#endif /*unsupported*/diff -Nur linux-2.6.36.orig/crypto/ocf/safe/sha1.h linux-2.6.36/crypto/ocf/safe/sha1.h--- linux-2.6.36.orig/crypto/ocf/safe/sha1.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/safe/sha1.h	2010-11-09 20:28:13.112495423 +0100@@ -0,0 +1,72 @@+/*	$FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $	*/+/*	$KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $	*/++/*+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the project nor the names of its contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */+/*+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)+ * based on: http://csrc.nist.gov/fips/fip180-1.txt+ * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>+ */++#ifndef _NETINET6_SHA1_H_+#define _NETINET6_SHA1_H_++struct sha1_ctxt {+	union {+		u_int8_t	b8[20];+		u_int32_t	b32[5];+	} h;+	union {+		u_int8_t	b8[8];+		u_int64_t	b64[1];+	} c;+	union {+		u_int8_t	b8[64];+		u_int32_t	b32[16];+	} m;+	u_int8_t	count;+};++#ifdef __KERNEL__+extern void sha1_init(struct sha1_ctxt *);+extern void sha1_pad(struct sha1_ctxt *);+extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);+extern void sha1_result(struct sha1_ctxt *, caddr_t);++/* compatibilty with other SHA1 source codes */+typedef struct sha1_ctxt SHA1_CTX;+#define SHA1Init(x)		sha1_init((x))+#define SHA1Update(x, y, z)	sha1_loop((x), (y), (z))+#define SHA1Final(x, y)		sha1_result((y), (x))+#endif /* __KERNEL__ */++#define	SHA1_RESULTLEN	(160/8)++#endif /*_NETINET6_SHA1_H_*/diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/Makefile linux-2.6.36/crypto/ocf/talitos/Makefile--- linux-2.6.36.orig/crypto/ocf/talitos/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/talitos/Makefile	2010-11-09 20:28:13.155214387 +0100@@ -0,0 +1,12 @@+# for SGlinux builds+-include $(ROOTDIR)/modules/.config++obj-$(CONFIG_OCF_TALITOS) += talitos.o++obj ?= .+EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/++ifdef TOPDIR+-include $(TOPDIR)/Rules.make+endif+diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos.c linux-2.6.36/crypto/ocf/talitos/talitos.c--- linux-2.6.36.orig/crypto/ocf/talitos/talitos.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/talitos/talitos.c	2010-11-09 20:28:13.192104548 +0100@@ -0,0 +1,1359 @@+/*+ * crypto/ocf/talitos/talitos.c+ *+ * An OCF-Linux module that uses Freescale's SEC to do the crypto.+ * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers+ *+ * Copyright (c) 2006 Freescale Semiconductor, Inc.+ *+ * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>+ * some code copied from files with the following:+ * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ * ---------------------------------------------------------------------------+ *+ * NOTES:+ *+ * The Freescale SEC (also known as 'talitos') resides on the+ * internal bus, and runs asynchronous to the processor core.  It has+ * a wide gamut of cryptographic acceleration features, including single-+ * pass IPsec (also known as algorithm chaining).  To properly utilize + * all of the SEC's performance enhancing features, further reworking + * of higher level code (framework, applications) will be necessary.+ *+ * The following table shows which SEC version is present in which devices:+ * + * Devices       SEC version+ *+ * 8272, 8248    SEC 1.0+ * 885, 875      SEC 1.2+ * 8555E, 8541E  SEC 2.0+ * 8349E         SEC 2.01+ * 8548E         SEC 2.1+ *+ * The following table shows the features offered by each SEC version:+ *+ * 	                       Max.   chan-+ * version  Bus I/F       Clock  nels  DEU AESU AFEU MDEU PKEU RNG KEU+ *+ * SEC 1.0  internal 64b  100MHz   4     1    1    1    1    1   1   0+ * SEC 1.2  internal 32b   66MHz   1     1    1    0    1    0   0   0+ * SEC 2.0  internal 64b  166MHz   4     1    1    1    1    1   1   0+ * SEC 2.01 internal 64b  166MHz   4     1    1    1    1    1   1   0+ * SEC 2.1  internal 64b  333MHz   4     1    1    1    1    1   1   1+ *+ * Each execution unit in the SEC has two modes of execution; channel and+ * slave/debug.  This driver employs the channel infrastructure in the+ * device for convenience.  Only the RNG is directly accessed due to the+ * convenience of its random fifo pool.  The relationship between the+ * channels and execution units is depicted in the following diagram:+ *+ *    -------   ------------+ * ---| ch0 |---|          |+ *    -------   |          |+ *              |          |------+-------+-------+-------+------------+ *    -------   |          |      |       |       |       |           |+ * ---| ch1 |---|          |      |       |       |       |           |+ *    -------   |          |   ------  ------  ------  ------      ------+ *              |controller|   |DEU |  |AESU|  |MDEU|  |PKEU| ...  |RNG |+ *    -------   |          |   ------  ------  ------  ------      ------+ * ---| ch2 |---|          |      |       |       |       |           |+ *    -------   |          |      |       |       |       |           |+ *              |          |------+-------+-------+-------+------------+ *    -------   |          |+ * ---| ch3 |---|          |+ *    -------   ------------+ *+ * Channel ch0 may drive an aes operation to the aes unit (AESU),+ * and, at the same time, ch1 may drive a message digest operation+ * to the mdeu. Each channel has an input descriptor FIFO, and the + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a+ * a buffer overrun error is triggered. The controller is responsible+ * for fetching the data from descriptor pointers, and passing the + * data to the appropriate EUs. The controller also writes the + * cryptographic operation's result to memory. The SEC notifies + * completion by triggering an interrupt and/or setting the 1st byte + * of the hdr field to 0xff.+ *+ * TODO:+ * o support more algorithms+ * o support more versions of the SEC+ * o add support for linux 2.4+ * o scatter-gather (sg) support+ * o add support for public key ops (PKEU)+ * o add statistics+ */++#ifndef AUTOCONF_INCLUDED+#include <linux/config.h>+#endif+#include <linux/module.h>+#include <linux/init.h>+#include <linux/interrupt.h>+#include <linux/spinlock.h>+#include <linux/random.h>+#include <linux/skbuff.h>+#include <asm/scatterlist.h>+#include <linux/dma-mapping.h>  /* dma_map_single() */+#include <linux/moduleparam.h>++#include <linux/version.h>+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)+#include <linux/platform_device.h>+#endif++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+#include <linux/of_platform.h>+#endif++#include <cryptodev.h>+#include <uio.h>++#define DRV_NAME "talitos" ++#include "talitos_dev.h"+#include "talitos_soft.h"++#define read_random(p,l) get_random_bytes(p,l)++const char talitos_driver_name[] = "Talitos OCF";+const char talitos_driver_version[] = "0.2";++static int talitos_newsession(device_t dev, u_int32_t *sidp,+								struct cryptoini *cri);+static int talitos_freesession(device_t dev, u_int64_t tid);+static int talitos_process(device_t dev, struct cryptop *crp, int hint);+static void dump_talitos_status(struct talitos_softc *sc);+static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td, +								int chsel);+static void talitos_doneprocessing(struct talitos_softc *sc);+static void talitos_init_device(struct talitos_softc *sc);+static void talitos_reset_device_master(struct talitos_softc *sc);+static void talitos_reset_device(struct talitos_softc *sc);+static void talitos_errorprocessing(struct talitos_softc *sc);+#ifdef CONFIG_PPC_MERGE+static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);+static int talitos_remove(struct of_device *ofdev);+#else+static int talitos_probe(struct platform_device *pdev);+static int talitos_remove(struct platform_device *pdev);+#endif+#ifdef CONFIG_OCF_RANDOMHARVEST+static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);+static void talitos_rng_init(struct talitos_softc *sc);+#endif++static device_method_t talitos_methods = {+	/* crypto device methods */+	DEVMETHOD(cryptodev_newsession,	talitos_newsession),+	DEVMETHOD(cryptodev_freesession,talitos_freesession),+	DEVMETHOD(cryptodev_process,	talitos_process),+};++#define debug talitos_debug+int talitos_debug = 0;+module_param(talitos_debug, int, 0644);+MODULE_PARM_DESC(talitos_debug, "Enable debug");++static inline void talitos_write(volatile unsigned *addr, u32 val)+{+        out_be32(addr, val);+}++static inline u32 talitos_read(volatile unsigned *addr)+{+        u32 val;+        val = in_be32(addr);+        return val;+}++static void dump_talitos_status(struct talitos_softc *sc)+{+	unsigned int v, v_hi, i, *ptr;+	v = talitos_read(sc->sc_base_addr + TALITOS_MCR);+	v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);+	printk(KERN_INFO "%s: MCR          0x%08x_%08x\n",+			device_get_nameunit(sc->sc_cdev), v, v_hi);+	v = talitos_read(sc->sc_base_addr + TALITOS_IMR);+	v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);+	printk(KERN_INFO "%s: IMR          0x%08x_%08x\n",+			device_get_nameunit(sc->sc_cdev), v, v_hi);+	v = talitos_read(sc->sc_base_addr + TALITOS_ISR);+	v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);+	printk(KERN_INFO "%s: ISR          0x%08x_%08x\n",+			device_get_nameunit(sc->sc_cdev), v, v_hi);+	for (i = 0; i < sc->sc_num_channels; i++) { +		v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + +			TALITOS_CH_CDPR);+		v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + +			TALITOS_CH_CDPR_HI);+		printk(KERN_INFO "%s: CDPR     ch%d 0x%08x_%08x\n", +				device_get_nameunit(sc->sc_cdev), i, v, v_hi);+	}+	for (i = 0; i < sc->sc_num_channels; i++) { +		v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + +			TALITOS_CH_CCPSR);+		v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + +			TALITOS_CH_CCPSR_HI);+		printk(KERN_INFO "%s: CCPSR    ch%d 0x%08x_%08x\n", +				device_get_nameunit(sc->sc_cdev), i, v, v_hi);+	}+	ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;+	for (i = 0; i < 16; i++) { +		v = talitos_read(ptr++); v_hi = talitos_read(ptr++);+		printk(KERN_INFO "%s: DESCBUF  ch0 0x%08x_%08x (tdp%02d)\n", +				device_get_nameunit(sc->sc_cdev), v, v_hi, i);+	}+	return;+}+++#ifdef CONFIG_OCF_RANDOMHARVEST+/* + * pull random numbers off the RNG FIFO, not exceeding amount available+ */+static int+talitos_read_random(void *arg, u_int32_t *buf, int maxwords)+{+	struct talitos_softc *sc = (struct talitos_softc *) arg;+	int rc;+	u_int32_t v;++	DPRINTF("%s()\n", __FUNCTION__);++	/* check for things like FIFO underflow */+	v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);+	if (unlikely(v)) {+		printk(KERN_ERR "%s: RNGISR_HI error %08x\n",+				device_get_nameunit(sc->sc_cdev), v);+		return 0;+	}+	/*+	 * OFL is number of available 64-bit words, +	 * shift and convert to a 32-bit word count+	 */+	v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);+	v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);+	if (maxwords > v)+		maxwords = v;+	for (rc = 0; rc < maxwords; rc++) {+		buf[rc] = talitos_read(sc->sc_base_addr + +			TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));+	}+	if (maxwords & 1) {+		/* +		 * RNG will complain with an AE in the RNGISR+		 * if we don't complete the pairs of 32-bit reads+		 * to its 64-bit register based FIFO+		 */+		v = talitos_read(sc->sc_base_addr + +			TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));+	}++	return rc;+}++static void+talitos_rng_init(struct talitos_softc *sc)+{+	u_int32_t v;++	DPRINTF("%s()\n", __FUNCTION__);+	/* reset RNG EU */+	v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);+	v |= TALITOS_RNGRCR_HI_SR;+	talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);+	while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI) +		& TALITOS_RNGSR_HI_RD) == 0)+			cpu_relax();+	/*+	 * we tell the RNG to start filling the RNG FIFO+	 * by writing the RNGDSR +	 */+	v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);+	talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);+	/*+	 * 64 bits of data will be pushed onto the FIFO every +	 * 256 SEC cycles until the FIFO is full.  The RNG then +	 * attempts to keep the FIFO full.+	 */+	v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);+	if (v) {+		printk(KERN_ERR "%s: RNGISR_HI error %08x\n",+			device_get_nameunit(sc->sc_cdev), v);+		return;+	}+	/*+	 * n.b. we need to add a FIPS test here - if the RNG is going +	 * to fail, it's going to fail at reset time+	 */+	return;+}+#endif /* CONFIG_OCF_RANDOMHARVEST */++/*+ * Generate a new software session.+ */+static int+talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)+{+	struct cryptoini *c, *encini = NULL, *macini = NULL;+	struct talitos_softc *sc = device_get_softc(dev);+	struct talitos_session *ses = NULL;+	int sesn;++	DPRINTF("%s()\n", __FUNCTION__);+	if (sidp == NULL || cri == NULL || sc == NULL) {+		DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);+		return EINVAL;+	}+	for (c = cri; c != NULL; c = c->cri_next) {+		if (c->cri_alg == CRYPTO_MD5 ||+		    c->cri_alg == CRYPTO_MD5_HMAC ||+		    c->cri_alg == CRYPTO_SHA1 ||+		    c->cri_alg == CRYPTO_SHA1_HMAC ||+		    c->cri_alg == CRYPTO_NULL_HMAC) {+			if (macini)+				return EINVAL;+			macini = c;+		} else if (c->cri_alg == CRYPTO_DES_CBC ||+		    c->cri_alg == CRYPTO_3DES_CBC ||+		    c->cri_alg == CRYPTO_AES_CBC ||+		    c->cri_alg == CRYPTO_NULL_CBC) {+			if (encini)+				return EINVAL;+			encini = c;+		} else {+			DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);+			return EINVAL;+		}+	}+	if (encini == NULL && macini == NULL)+		return EINVAL;+	if (encini) {	+		/* validate key length */+		switch (encini->cri_alg) {+		case CRYPTO_DES_CBC:+			if (encini->cri_klen != 64)+				return EINVAL;+			break;+		case CRYPTO_3DES_CBC:+			if (encini->cri_klen != 192) {+				return EINVAL;+			}+			break;+		case CRYPTO_AES_CBC:+			if (encini->cri_klen != 128 &&+			    encini->cri_klen != 192 &&+			    encini->cri_klen != 256)+				return EINVAL;+			break;+		default:+			DPRINTF("UNKNOWN encini->cri_alg %d\n", +				encini->cri_alg);+			return EINVAL;+		}+	}++	if (sc->sc_sessions == NULL) {+		ses = sc->sc_sessions = (struct talitos_session *)+			kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);+		if (ses == NULL)+			return ENOMEM;+		memset(ses, 0, sizeof(struct talitos_session));+		sesn = 0;+		sc->sc_nsessions = 1;+	} else {+		for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {+			if (sc->sc_sessions[sesn].ses_used == 0) {+				ses = &sc->sc_sessions[sesn];+				break;+			}+		}++		if (ses == NULL) {+			/* allocating session */+			sesn = sc->sc_nsessions;+			ses = (struct talitos_session *) kmalloc(+				(sesn + 1) * sizeof(struct talitos_session), +				SLAB_ATOMIC);+			if (ses == NULL)+				return ENOMEM;+			memset(ses, 0,+				(sesn + 1) * sizeof(struct talitos_session));+			memcpy(ses, sc->sc_sessions, +				sesn * sizeof(struct talitos_session));+			memset(sc->sc_sessions, 0,+				sesn * sizeof(struct talitos_session));+			kfree(sc->sc_sessions);+			sc->sc_sessions = ses;+			ses = &sc->sc_sessions[sesn];+			sc->sc_nsessions++;+		}+	}++	ses->ses_used = 1;++	if (encini) {+		/* get an IV */+		/* XXX may read fewer than requested */+		read_random(ses->ses_iv, sizeof(ses->ses_iv));++		ses->ses_klen = (encini->cri_klen + 7) / 8;+		memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);+		if (macini) {+			/* doing hash on top of cipher */+			ses->ses_hmac_len = (macini->cri_klen + 7) / 8;+			memcpy(ses->ses_hmac, macini->cri_key,+				ses->ses_hmac_len);+		}+	} else if (macini) {+		/* doing hash */+		ses->ses_klen = (macini->cri_klen + 7) / 8;+		memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);+	}++	/* back compat way of determining MSC result len */+	if (macini) {+		ses->ses_mlen = macini->cri_mlen;+		if (ses->ses_mlen == 0) {+			if (macini->cri_alg == CRYPTO_MD5_HMAC)+				ses->ses_mlen = MD5_HASH_LEN;+			else+				ses->ses_mlen = SHA1_HASH_LEN;+		}+	}++	/* really should make up a template td here, +	 * and only fill things like i/o and direction in process() */++	/* assign session ID */+	*sidp = TALITOS_SID(sc->sc_num, sesn);+	return 0;+}++/*+ * Deallocate a session.+ */+static int+talitos_freesession(device_t dev, u_int64_t tid)+{+	struct talitos_softc *sc = device_get_softc(dev);+	int session, ret;+	u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;++	if (sc == NULL)+		return EINVAL;+	session = TALITOS_SESSION(sid);+	if (session < sc->sc_nsessions) {+		memset(&sc->sc_sessions[session], 0,+			sizeof(sc->sc_sessions[session]));+		ret = 0;+	} else+		ret = EINVAL;+	return ret;+}++/*+ * launch device processing - it will come back with done notification + * in the form of an interrupt and/or HDR_DONE_BITS in header + */+static int +talitos_submit(+	struct talitos_softc *sc,+	struct talitos_desc *td,+	int chsel)+{+	u_int32_t v;++	v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);+	talitos_write(sc->sc_base_addr + +		chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);+	talitos_write(sc->sc_base_addr + +		chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);+	return 0;+}++static int+talitos_process(device_t dev, struct cryptop *crp, int hint)+{+	int i, err = 0, ivsize;+	struct talitos_softc *sc = device_get_softc(dev);+	struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;+	caddr_t iv;+	struct talitos_session *ses;+	struct talitos_desc *td;+	unsigned long flags;+	/* descriptor mappings */+	int hmac_key, hmac_data, cipher_iv, cipher_key, +		in_fifo, out_fifo, cipher_iv_out;+	static int chsel = -1;++	DPRINTF("%s()\n", __FUNCTION__);++	if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {+		return EINVAL;+	}+	crp->crp_etype = 0;+	if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {+		return EINVAL;+	}++	ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];++        /* enter the channel scheduler */ +	spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);++	/* reuse channel that already had/has requests for the required EU */+	for (i = 0; i < sc->sc_num_channels; i++) {+		if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)+			break;+	}+	if (i == sc->sc_num_channels) {+		/*+		 * haven't seen this algo the last sc_num_channels or more+		 * use round robin in this case+	 	 * nb: sc->sc_num_channels must be power of 2 +		 */+		chsel = (chsel + 1) & (sc->sc_num_channels - 1);+	} else {+		/*+		 * matches channel with same target execution unit; +		 * use same channel in this case+		 */+		chsel = i;+	}+	sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;++        /* release the channel scheduler lock */ +	spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);++	/* acquire the selected channel fifo lock */+	spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);++	/* find and reserve next available descriptor-cryptop pair */+	for (i = 0; i < sc->sc_chfifo_len; i++) {+		if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {+			/* +			 * ensure correct descriptor formation by+			 * avoiding inadvertently setting "optional" entries+			 * e.g. not using "optional" dptr2 for MD/HMAC descs+			 */+			memset(&sc->sc_chnfifo[chsel][i].cf_desc,+				0, sizeof(*td));+			/* reserve it with done notification request bit */+			sc->sc_chnfifo[chsel][i].cf_desc.hdr |= +				TALITOS_DONE_NOTIFY;+			break;+		}+	}+	spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);++	if (i == sc->sc_chfifo_len) {+		/* fifo full */+		err = ERESTART;+		goto errout;+	}+	+	td = &sc->sc_chnfifo[chsel][i].cf_desc;+	sc->sc_chnfifo[chsel][i].cf_crp = crp;++	crd1 = crp->crp_desc;+	if (crd1 == NULL) {+		err = EINVAL;+		goto errout;+	}+	crd2 = crd1->crd_next;+	/* prevent compiler warning */+	hmac_key = 0;+	hmac_data = 0;+	if (crd2 == NULL) {+		td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;+		/* assign descriptor dword ptr mappings for this desc. type */+		cipher_iv = 1;+		cipher_key = 2;+		in_fifo = 3;+		cipher_iv_out = 5;+		if (crd1->crd_alg == CRYPTO_MD5_HMAC ||+		    crd1->crd_alg == CRYPTO_SHA1_HMAC ||+		    crd1->crd_alg == CRYPTO_SHA1 ||+		    crd1->crd_alg == CRYPTO_MD5) {+			out_fifo = 5;+			maccrd = crd1;+			enccrd = NULL;+		} else if (crd1->crd_alg == CRYPTO_DES_CBC ||+		    crd1->crd_alg == CRYPTO_3DES_CBC ||+		    crd1->crd_alg == CRYPTO_AES_CBC ||+		    crd1->crd_alg == CRYPTO_ARC4) {+			out_fifo = 4;+			maccrd = NULL;+			enccrd = crd1;+		} else {+			DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);+			err = EINVAL;+			goto errout;+		}+	} else {+		if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {+			td->hdr |= TD_TYPE_IPSEC_ESP;+		} else {+			DPRINTF("unimplemented: multiple descriptor ipsec\n");+			err = EINVAL;+			goto errout;+		}+		/* assign descriptor dword ptr mappings for this desc. type */+		hmac_key = 0;+		hmac_data = 1;+		cipher_iv = 2;+		cipher_key = 3;+		in_fifo = 4;+		out_fifo = 5;+		cipher_iv_out = 6;+		if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||+                     crd1->crd_alg == CRYPTO_SHA1_HMAC ||+                     crd1->crd_alg == CRYPTO_MD5 ||+                     crd1->crd_alg == CRYPTO_SHA1) &&+		    (crd2->crd_alg == CRYPTO_DES_CBC ||+		     crd2->crd_alg == CRYPTO_3DES_CBC ||+		     crd2->crd_alg == CRYPTO_AES_CBC ||+		     crd2->crd_alg == CRYPTO_ARC4) &&+		    ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {+			maccrd = crd1;+			enccrd = crd2;+		} else if ((crd1->crd_alg == CRYPTO_DES_CBC ||+		     crd1->crd_alg == CRYPTO_ARC4 ||+		     crd1->crd_alg == CRYPTO_3DES_CBC ||+		     crd1->crd_alg == CRYPTO_AES_CBC) &&+		    (crd2->crd_alg == CRYPTO_MD5_HMAC ||+                     crd2->crd_alg == CRYPTO_SHA1_HMAC ||+                     crd2->crd_alg == CRYPTO_MD5 ||+                     crd2->crd_alg == CRYPTO_SHA1) &&+		    (crd1->crd_flags & CRD_F_ENCRYPT)) {+			enccrd = crd1;+			maccrd = crd2;+		} else {+			/* We cannot order the SEC as requested */+			printk("%s: cannot do the order\n",+					device_get_nameunit(sc->sc_cdev));+			err = EINVAL;+			goto errout;+		}+	}+	/* assign in_fifo and out_fifo based on input/output struct type */+	if (crp->crp_flags & CRYPTO_F_SKBUF) {+		/* using SKB buffers */+		struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;+		if (skb_shinfo(skb)->nr_frags) {+			printk("%s: skb frags unimplemented\n",+					device_get_nameunit(sc->sc_cdev));+			err = EINVAL;+			goto errout;+		}+		td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data, +			skb->len, DMA_TO_DEVICE);+		td->ptr[in_fifo].len = skb->len;+		td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data, +			skb->len, DMA_TO_DEVICE);+		td->ptr[out_fifo].len = skb->len;+		td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,+			skb->len, DMA_TO_DEVICE);+	} else if (crp->crp_flags & CRYPTO_F_IOV) {+		/* using IOV buffers */+		struct uio *uiop = (struct uio *)crp->crp_buf;+		if (uiop->uio_iovcnt > 1) {+			printk("%s: iov frags unimplemented\n",+					device_get_nameunit(sc->sc_cdev));+			err = EINVAL;+			goto errout;+		}+		td->ptr[in_fifo].ptr = dma_map_single(NULL,+			uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);+		td->ptr[in_fifo].len = crp->crp_ilen;+		/* crp_olen is never set; always use crp_ilen */+		td->ptr[out_fifo].ptr = dma_map_single(NULL,+			uiop->uio_iov->iov_base,+			crp->crp_ilen, DMA_TO_DEVICE);+		td->ptr[out_fifo].len = crp->crp_ilen;+	} else {+		/* using contig buffers */+		td->ptr[in_fifo].ptr = dma_map_single(NULL,+			crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);+		td->ptr[in_fifo].len = crp->crp_ilen;+		td->ptr[out_fifo].ptr = dma_map_single(NULL,+			crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);+		td->ptr[out_fifo].len = crp->crp_ilen;+	}+	if (enccrd) {+		switch (enccrd->crd_alg) {+		case CRYPTO_3DES_CBC:+			td->hdr |= TALITOS_MODE0_DEU_3DES;+			/* FALLTHROUGH */+		case CRYPTO_DES_CBC:+			td->hdr |= TALITOS_SEL0_DEU+				|  TALITOS_MODE0_DEU_CBC;+			if (enccrd->crd_flags & CRD_F_ENCRYPT)+				td->hdr |= TALITOS_MODE0_DEU_ENC;+			ivsize = 2*sizeof(u_int32_t);+			DPRINTF("%cDES ses %d ch %d len %d\n",+				(td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',+				(u32)TALITOS_SESSION(crp->crp_sid),+				chsel, td->ptr[in_fifo].len);+			break;+		case CRYPTO_AES_CBC:+			td->hdr |= TALITOS_SEL0_AESU+				|  TALITOS_MODE0_AESU_CBC;+			if (enccrd->crd_flags & CRD_F_ENCRYPT)+				td->hdr |= TALITOS_MODE0_AESU_ENC;+			ivsize = 4*sizeof(u_int32_t);+			DPRINTF("AES  ses %d ch %d len %d\n",+				(u32)TALITOS_SESSION(crp->crp_sid),+				chsel, td->ptr[in_fifo].len);+			break;+		default:+			printk("%s: unimplemented enccrd->crd_alg %d\n",+					device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);+			err = EINVAL;+			goto errout;+		}+		/*+		 * Setup encrypt/decrypt state.  When using basic ops+		 * we can't use an inline IV because hash/crypt offset+		 * must be from the end of the IV to the start of the+		 * crypt data and this leaves out the preceding header+		 * from the hash calculation.  Instead we place the IV+		 * in the state record and set the hash/crypt offset to+		 * copy both the header+IV.+		 */+		if (enccrd->crd_flags & CRD_F_ENCRYPT) {+			td->hdr |= TALITOS_DIR_OUTBOUND; +			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)+				iv = enccrd->crd_iv;+			else+				iv = (caddr_t) ses->ses_iv;+			if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {+				crypto_copyback(crp->crp_flags, crp->crp_buf,+				    enccrd->crd_inject, ivsize, iv);+			}+		} else {+			td->hdr |= TALITOS_DIR_INBOUND; +			if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {+				iv = enccrd->crd_iv;+				bcopy(enccrd->crd_iv, iv, ivsize);+			} else {+				iv = (caddr_t) ses->ses_iv;+				crypto_copydata(crp->crp_flags, crp->crp_buf,+				    enccrd->crd_inject, ivsize, iv);+			}+		}+		td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize, +			DMA_TO_DEVICE);+		td->ptr[cipher_iv].len = ivsize;+		/*+		 * we don't need the cipher iv out length/pointer+		 * field to do ESP IPsec. Therefore we set the len field as 0,+		 * which tells the SEC not to do anything with this len/ptr+		 * field. Previously, when length/pointer as pointing to iv,+		 * it gave us corruption of packets.+		 */+		td->ptr[cipher_iv_out].len = 0;+	}+	if (enccrd && maccrd) {+		/* this is ipsec only for now */+		td->hdr |= TALITOS_SEL1_MDEU+			|  TALITOS_MODE1_MDEU_INIT+			|  TALITOS_MODE1_MDEU_PAD;+		switch (maccrd->crd_alg) {+			case	CRYPTO_MD5:	+				td->hdr |= TALITOS_MODE1_MDEU_MD5;+				break;+			case	CRYPTO_MD5_HMAC:	+				td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;+				break;+			case	CRYPTO_SHA1:	+				td->hdr |= TALITOS_MODE1_MDEU_SHA1;+				break;+			case	CRYPTO_SHA1_HMAC:	+				td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;+				break;+			default:+				/* We cannot order the SEC as requested */+				printk("%s: cannot do the order\n",+						device_get_nameunit(sc->sc_cdev));+				err = EINVAL;+				goto errout;+		}+		if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||+		   (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {+			/*+			 * The offset from hash data to the start of+			 * crypt data is the difference in the skips.+			 */+			/* ipsec only for now */+			td->ptr[hmac_key].ptr = dma_map_single(NULL, +				ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);+			td->ptr[hmac_key].len = ses->ses_hmac_len;+			td->ptr[in_fifo].ptr  += enccrd->crd_skip;+			td->ptr[in_fifo].len  =  enccrd->crd_len;+			td->ptr[out_fifo].ptr += enccrd->crd_skip;+			td->ptr[out_fifo].len =  enccrd->crd_len;+			/* bytes of HMAC to postpend to ciphertext */+			td->ptr[out_fifo].extent =  ses->ses_mlen;+			td->ptr[hmac_data].ptr += maccrd->crd_skip; +			td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;+		}+		if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {+			printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",+					device_get_nameunit(sc->sc_cdev));+		}+	}+	if (!enccrd && maccrd) {+		/* single MD5 or SHA */+		td->hdr |= TALITOS_SEL0_MDEU+				|  TALITOS_MODE0_MDEU_INIT+				|  TALITOS_MODE0_MDEU_PAD;+		switch (maccrd->crd_alg) {+			case	CRYPTO_MD5:	+				td->hdr |= TALITOS_MODE0_MDEU_MD5;+				DPRINTF("MD5  ses %d ch %d len %d\n",+					(u32)TALITOS_SESSION(crp->crp_sid), +					chsel, td->ptr[in_fifo].len);+				break;+			case	CRYPTO_MD5_HMAC:	+				td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;+				break;+			case	CRYPTO_SHA1:	+				td->hdr |= TALITOS_MODE0_MDEU_SHA1;+				DPRINTF("SHA1 ses %d ch %d len %d\n",+					(u32)TALITOS_SESSION(crp->crp_sid), +					chsel, td->ptr[in_fifo].len);+				break;+			case	CRYPTO_SHA1_HMAC:	+				td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;+				break;+			default:+				/* We cannot order the SEC as requested */+				DPRINTF("cannot do the order\n");+				err = EINVAL;+				goto errout;+		}++		if (crp->crp_flags & CRYPTO_F_IOV)+			td->ptr[out_fifo].ptr += maccrd->crd_inject;++		if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||+		   (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {+			td->ptr[hmac_key].ptr = dma_map_single(NULL, +				ses->ses_hmac, ses->ses_hmac_len, +				DMA_TO_DEVICE);+			td->ptr[hmac_key].len = ses->ses_hmac_len;+		}+	} +	else {+		/* using process key (session data has duplicate) */+		td->ptr[cipher_key].ptr = dma_map_single(NULL, +			enccrd->crd_key, (enccrd->crd_klen + 7) / 8, +			DMA_TO_DEVICE);+		td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;+	}+	/* descriptor complete - GO! */+	return talitos_submit(sc, td, chsel);++errout:+	if (err != ERESTART) {+		crp->crp_etype = err;+		crypto_done(crp);+	}+	return err;+}++/* go through all channels descriptors, notifying OCF what has + * _and_hasn't_ successfully completed and reset the device + * (otherwise it's up to decoding desc hdrs!)+ */+static void talitos_errorprocessing(struct talitos_softc *sc)+{+	unsigned long flags;+	int i, j;++	/* disable further scheduling until under control */+	spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);++	if (debug) dump_talitos_status(sc);+	/* go through descriptors, try and salvage those successfully done, +	 * and EIO those that weren't+	 */+	for (i = 0; i < sc->sc_num_channels; i++) {+		spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);+		for (j = 0; j < sc->sc_chfifo_len; j++) {+			if (sc->sc_chnfifo[i][j].cf_desc.hdr) {+				if ((sc->sc_chnfifo[i][j].cf_desc.hdr +					& TALITOS_HDR_DONE_BITS) +					!= TALITOS_HDR_DONE_BITS) {+					/* this one didn't finish */+					/* signify in crp->etype */+					sc->sc_chnfifo[i][j].cf_crp->crp_etype +						= EIO;+				}+			} else+				continue; /* free entry */+			/* either way, notify ocf */+			crypto_done(sc->sc_chnfifo[i][j].cf_crp);+			/* and tag it available again+			 *+			 * memset to ensure correct descriptor formation by+			 * avoiding inadvertently setting "optional" entries+			 * e.g. not using "optional" dptr2 MD/HMAC processing+			 */+			memset(&sc->sc_chnfifo[i][j].cf_desc,+				0, sizeof(struct talitos_desc));+		}+		spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);+	}+	/* reset and initialize the SEC h/w device */+	talitos_reset_device(sc);+	talitos_init_device(sc);+#ifdef CONFIG_OCF_RANDOMHARVEST+	if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)+		talitos_rng_init(sc);+#endif++	/* Okay. Stand by. */+	spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);++	return;+}++/* go through all channels descriptors, notifying OCF what's been done */+static void talitos_doneprocessing(struct talitos_softc *sc)+{+	unsigned long flags;+	int i, j;++	/* go through descriptors looking for done bits */+	for (i = 0; i < sc->sc_num_channels; i++) {+		spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);+		for (j = 0; j < sc->sc_chfifo_len; j++) {+			/* descriptor has done bits set? */+			if ((sc->sc_chnfifo[i][j].cf_desc.hdr +				& TALITOS_HDR_DONE_BITS) +				== TALITOS_HDR_DONE_BITS) {+				/* notify ocf */+				crypto_done(sc->sc_chnfifo[i][j].cf_crp);+				/* and tag it available again+				 *+				 * memset to ensure correct descriptor formation by+				 * avoiding inadvertently setting "optional" entries+				 * e.g. not using "optional" dptr2 MD/HMAC processing+				 */+				memset(&sc->sc_chnfifo[i][j].cf_desc,+					0, sizeof(struct talitos_desc));+			}+		}+		spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);+	}+	return;+}++static irqreturn_t+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)+talitos_intr(int irq, void *arg)+#else+talitos_intr(int irq, void *arg, struct pt_regs *regs)+#endif+{+	struct talitos_softc *sc = arg;+	u_int32_t v, v_hi;+	+	/* ack */+	v = talitos_read(sc->sc_base_addr + TALITOS_ISR);+	v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);+	talitos_write(sc->sc_base_addr + TALITOS_ICR, v);+	talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);++	if (unlikely(v & TALITOS_ISR_ERROR)) {+		/* Okay, Houston, we've had a problem here. */+		printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",+				device_get_nameunit(sc->sc_cdev), v, v_hi);+		talitos_errorprocessing(sc);+	} else+	if (likely(v & TALITOS_ISR_DONE)) {+		talitos_doneprocessing(sc);+	}+	return IRQ_HANDLED;+}++/*+ * Initialize registers we need to touch only once.+ */+static void+talitos_init_device(struct talitos_softc *sc)+{+	u_int32_t v;+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	/* init all channels */+	for (i = 0; i < sc->sc_num_channels; i++) {+		v = talitos_read(sc->sc_base_addr + +			i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);+		v |= TALITOS_CH_CCCR_HI_CDWE+		  |  TALITOS_CH_CCCR_HI_CDIE;  /* invoke interrupt if done */+		talitos_write(sc->sc_base_addr + +			i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);+	}+	/* enable all interrupts */+	v = talitos_read(sc->sc_base_addr + TALITOS_IMR);+	v |= TALITOS_IMR_ALL;+	talitos_write(sc->sc_base_addr + TALITOS_IMR, v);+	v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);+	v |= TALITOS_IMR_HI_ERRONLY;+	talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);+	return;+}++/*+ * set the master reset bit on the device.+ */+static void+talitos_reset_device_master(struct talitos_softc *sc)+{+	u_int32_t v;++	/* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */+	v = talitos_read(sc->sc_base_addr + TALITOS_MCR);+	talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);++	while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)+		cpu_relax();++	return;+}++/*+ * Resets the device.  Values in the registers are left as is+ * from the reset (i.e. initial values are assigned elsewhere).+ */+static void+talitos_reset_device(struct talitos_softc *sc)+{+	u_int32_t v;+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	/*+	 * Master reset+	 * errata documentation: warning: certain SEC interrupts +	 * are not fully cleared by writing the MCR:SWR bit, +	 * set bit twice to completely reset +	 */+	talitos_reset_device_master(sc);	/* once */+	talitos_reset_device_master(sc);	/* and once again */+	+	/* reset all channels */+	for (i = 0; i < sc->sc_num_channels; i++) {+		v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET ++			TALITOS_CH_CCCR);+		talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET ++			TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);+	}+}++/* Set up the crypto device structure, private data,+ * and anything else we need before we start */+#ifdef CONFIG_PPC_MERGE+static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)+#else+static int talitos_probe(struct platform_device *pdev)+#endif+{+	struct talitos_softc *sc = NULL;+	struct resource *r;+#ifdef CONFIG_PPC_MERGE+	struct device *device = &ofdev->dev;+	struct device_node *np = ofdev->node;+	const unsigned int *prop;+	int err;+	struct resource res;+#endif+	static int num_chips = 0;+	int rc;+	int i;++	DPRINTF("%s()\n", __FUNCTION__);++	sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);+	if (!sc)+		return -ENOMEM;+	memset(sc, 0, sizeof(*sc));++	softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);++	sc->sc_irq = -1;+	sc->sc_cid = -1;+#ifndef CONFIG_PPC_MERGE+	sc->sc_dev = pdev;+#endif+	sc->sc_num = num_chips++;++#ifdef CONFIG_PPC_MERGE+	dev_set_drvdata(device, sc);+#else+	platform_set_drvdata(sc->sc_dev, sc);+#endif++	/* get the irq line */+#ifdef CONFIG_PPC_MERGE+	err = of_address_to_resource(np, 0, &res);+	if (err)+		return -EINVAL;+	r = &res;++	sc->sc_irq = irq_of_parse_and_map(np, 0);+#else+	/* get a pointer to the register memory */+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);++	sc->sc_irq = platform_get_irq(pdev, 0);+#endif+	rc = request_irq(sc->sc_irq, talitos_intr, 0,+			device_get_nameunit(sc->sc_cdev), sc);+	if (rc) {+		printk(KERN_ERR "%s: failed to hook irq %d\n", +				device_get_nameunit(sc->sc_cdev), sc->sc_irq);+		sc->sc_irq = -1;+		goto out;+	}++	sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));+	if (!sc->sc_base_addr) {+		printk(KERN_ERR "%s: failed to ioremap\n",+				device_get_nameunit(sc->sc_cdev));+		goto out;+	}++	/* figure out our SEC's properties and capabilities */+	sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32+		 | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);+	DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);++#ifdef CONFIG_PPC_MERGE+	/* get SEC properties from device tree, defaulting to SEC 2.0 */++	prop = of_get_property(np, "num-channels", NULL);+	sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;++	prop = of_get_property(np, "channel-fifo-len", NULL);+	sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;++	prop = of_get_property(np, "exec-units-mask", NULL);+	sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;++	prop = of_get_property(np, "descriptor-types-mask", NULL);+	sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;+#else+	/* bulk should go away with openfirmware flat device tree support */+	if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {+		sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;+		sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;+		sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;+		sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;+	} else {+		printk(KERN_ERR "%s: failed to id device\n",+				device_get_nameunit(sc->sc_cdev));+		goto out;+	}+#endif++	/* + 1 is for the meta-channel lock used by the channel scheduler */+	sc->sc_chnfifolock = (spinlock_t *) kmalloc(+		(sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);+	if (!sc->sc_chnfifolock)+		goto out;+	for (i = 0; i < sc->sc_num_channels + 1; i++) {+		spin_lock_init(&sc->sc_chnfifolock[i]);+	}++	sc->sc_chnlastalg = (int *) kmalloc(+		sc->sc_num_channels * sizeof(int), GFP_KERNEL);+	if (!sc->sc_chnlastalg)+		goto out;+	memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));++	sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(+		sc->sc_num_channels * sizeof(struct desc_cryptop_pair *), +		GFP_KERNEL);+	if (!sc->sc_chnfifo)+		goto out;+	for (i = 0; i < sc->sc_num_channels; i++) {+		sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(+			sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair), +			GFP_KERNEL);+		if (!sc->sc_chnfifo[i])+			goto out;+		memset(sc->sc_chnfifo[i], 0, +			sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));+	}++	/* reset and initialize the SEC h/w device */+	talitos_reset_device(sc);+	talitos_init_device(sc);++	sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);+	if (sc->sc_cid < 0) {+		printk(KERN_ERR "%s: could not get crypto driver id\n",+				device_get_nameunit(sc->sc_cdev));+		goto out;+	}++	/* register algorithms with the framework */+	printk("%s:", device_get_nameunit(sc->sc_cdev));++	if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)  {+		printk(" rng");+#ifdef CONFIG_OCF_RANDOMHARVEST+		talitos_rng_init(sc);+		crypto_rregister(sc->sc_cid, talitos_read_random, sc);+#endif+	}+	if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {+		printk(" des/3des");+		crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);+		crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);+	}+	if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {+		printk(" aes");+		crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);+	}+	if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {+		printk(" md5");+		crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);+		/* HMAC support only with IPsec for now */+		crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);+		printk(" sha1");+		crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);+		/* HMAC support only with IPsec for now */+		crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);+	}+	printk("\n");+	return 0;++out:+#ifndef CONFIG_PPC_MERGE+	talitos_remove(pdev);+#endif+	return -ENOMEM;+}++#ifdef CONFIG_PPC_MERGE+static int talitos_remove(struct of_device *ofdev)+#else+static int talitos_remove(struct platform_device *pdev)+#endif+{+#ifdef CONFIG_PPC_MERGE+	struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);+#else+	struct talitos_softc *sc = platform_get_drvdata(pdev);+#endif+	int i;++	DPRINTF("%s()\n", __FUNCTION__);+	if (sc->sc_cid >= 0)+		crypto_unregister_all(sc->sc_cid);+	if (sc->sc_chnfifo) {+		for (i = 0; i < sc->sc_num_channels; i++)+			if (sc->sc_chnfifo[i])+				kfree(sc->sc_chnfifo[i]);+		kfree(sc->sc_chnfifo);+	}+	if (sc->sc_chnlastalg)+		kfree(sc->sc_chnlastalg);+	if (sc->sc_chnfifolock)+		kfree(sc->sc_chnfifolock);+	if (sc->sc_irq != -1)+		free_irq(sc->sc_irq, sc);+	if (sc->sc_base_addr)+		iounmap((void *) sc->sc_base_addr);+	kfree(sc);+	return 0;+}++#ifdef CONFIG_PPC_MERGE+static struct of_device_id talitos_match[] = {+	{+		.type = "crypto",+		.compatible = "talitos",+	},+	{},+};++MODULE_DEVICE_TABLE(of, talitos_match);++static struct of_platform_driver talitos_driver = {+	.name		= DRV_NAME,+	.match_table	= talitos_match,+	.probe		= talitos_probe,+	.remove		= talitos_remove,+};++static int __init talitos_init(void)+{+	return of_register_platform_driver(&talitos_driver);+}++static void __exit talitos_exit(void)+{+	of_unregister_platform_driver(&talitos_driver);+}+#else+/* Structure for a platform device driver */+static struct platform_driver talitos_driver = {+	.probe = talitos_probe,+	.remove = talitos_remove,+	.driver = {+		.name = "fsl-sec2",+	}+};++static int __init talitos_init(void)+{+	return platform_driver_register(&talitos_driver);+}++static void __exit talitos_exit(void)+{+	platform_driver_unregister(&talitos_driver);+}+#endif++module_init(talitos_init);+module_exit(talitos_exit);++MODULE_LICENSE("Dual BSD/GPL");+MODULE_AUTHOR("kim.phillips@freescale.com");+MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.36/crypto/ocf/talitos/talitos_dev.h--- linux-2.6.36.orig/crypto/ocf/talitos/talitos_dev.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/talitos/talitos_dev.h	2010-11-09 20:28:13.232495491 +0100@@ -0,0 +1,277 @@+/*+ * Freescale SEC (talitos) device dependent data structures+ *+ * Copyright (c) 2006 Freescale Semiconductor, Inc.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ */++/* device ID register values */+#define TALITOS_ID_SEC_2_0	0x40+#define TALITOS_ID_SEC_2_1	0x40 /* cross ref with IP block revision reg */++/*+ * following num_channels, channel-fifo-depth, exec-unit-mask, and + * descriptor-types-mask are for forward-compatibility with openfirmware+ * flat device trees+ */++/*+ *  num_channels : the number of channels available in each SEC version.+ */++/* n.b. this driver requires these values be a power of 2 */+#define TALITOS_NCHANNELS_SEC_1_0	4+#define TALITOS_NCHANNELS_SEC_1_2	1+#define TALITOS_NCHANNELS_SEC_2_0	4+#define TALITOS_NCHANNELS_SEC_2_01	4+#define TALITOS_NCHANNELS_SEC_2_1	4+#define TALITOS_NCHANNELS_SEC_2_4	4++/*+ *  channel-fifo-depth : The number of descriptor+ *  pointers a channel fetch fifo can hold.+ */+#define TALITOS_CHFIFOLEN_SEC_1_0	1+#define TALITOS_CHFIFOLEN_SEC_1_2	1+#define TALITOS_CHFIFOLEN_SEC_2_0	24+#define TALITOS_CHFIFOLEN_SEC_2_01	24+#define TALITOS_CHFIFOLEN_SEC_2_1	24+#define TALITOS_CHFIFOLEN_SEC_2_4	24++/* + *  exec-unit-mask : The bitmask representing what Execution Units (EUs)+ *  are available. EU information should be encoded following the SEC's + *  EU_SEL0 bitfield documentation, i.e. as follows:+ * + *    bit 31 = set if SEC permits no-EU selection (should be always set)+ *    bit 30 = set if SEC has the ARC4 EU (AFEU)+ *    bit 29 = set if SEC has the des/3des EU (DEU)+ *    bit 28 = set if SEC has the message digest EU (MDEU)+ *    bit 27 = set if SEC has the random number generator EU (RNG)+ *    bit 26 = set if SEC has the public key EU (PKEU)+ *    bit 25 = set if SEC has the aes EU (AESU)+ *    bit 24 = set if SEC has the Kasumi EU (KEU)+ * + */+#define TALITOS_HAS_EU_NONE		(1<<0)+#define TALITOS_HAS_EU_AFEU		(1<<1)+#define TALITOS_HAS_EU_DEU		(1<<2)+#define TALITOS_HAS_EU_MDEU		(1<<3)+#define TALITOS_HAS_EU_RNG		(1<<4)+#define TALITOS_HAS_EU_PKEU		(1<<5)+#define TALITOS_HAS_EU_AESU		(1<<6)+#define TALITOS_HAS_EU_KEU		(1<<7)++/* the corresponding masks for each SEC version */+#define TALITOS_HAS_EUS_SEC_1_0		0x7f+#define TALITOS_HAS_EUS_SEC_1_2		0x4d+#define TALITOS_HAS_EUS_SEC_2_0		0x7f+#define TALITOS_HAS_EUS_SEC_2_01	0x7f+#define TALITOS_HAS_EUS_SEC_2_1		0xff+#define TALITOS_HAS_EUS_SEC_2_4		0x7f++/*+ *  descriptor-types-mask : The bitmask representing what descriptors+ *  are available. Descriptor type information should be encoded + *  following the SEC's Descriptor Header Dword DESC_TYPE field + *  documentation, i.e. as follows:+ *+ *    bit 0  = set if SEC supports the aesu_ctr_nonsnoop desc. type+ *    bit 1  = set if SEC supports the ipsec_esp descriptor type+ *    bit 2  = set if SEC supports the common_nonsnoop desc. type+ *    bit 3  = set if SEC supports the 802.11i AES ccmp desc. type+ *    bit 4  = set if SEC supports the hmac_snoop_no_afeu desc. type+ *    bit 5  = set if SEC supports the srtp descriptor type+ *    bit 6  = set if SEC supports the non_hmac_snoop_no_afeu desc.type+ *    bit 7  = set if SEC supports the pkeu_assemble descriptor type+ *    bit 8  = set if SEC supports the aesu_key_expand_output desc.type+ *    bit 9  = set if SEC supports the pkeu_ptmul descriptor type+ *    bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type+ *    bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type+ *+ *  ..and so on and so forth.+ */+#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP	(1<<0)+#define TALITOS_HAS_DT_IPSEC_ESP		(1<<1)+#define TALITOS_HAS_DT_COMMON_NONSNOOP		(1<<2)++/* the corresponding masks for each SEC version */+#define TALITOS_HAS_DESCTYPES_SEC_2_0	0x01010ebf+#define TALITOS_HAS_DESCTYPES_SEC_2_1	0x012b0ebf++/* + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register+ */++/* global register offset addresses */+#define TALITOS_ID		0x1020+#define TALITOS_ID_HI		0x1024+#define TALITOS_MCR		0x1030		/* master control register */+#define TALITOS_MCR_HI		0x1038		/* master control register */+#define TALITOS_MCR_SWR		0x1+#define TALITOS_IMR		0x1008		/* interrupt mask register */+#define TALITOS_IMR_ALL		0x00010fff	/* enable all interrupts mask */+#define TALITOS_IMR_ERRONLY	0x00010aaa	/* enable error interrupts */+#define TALITOS_IMR_HI		0x100C		/* interrupt mask register */+#define TALITOS_IMR_HI_ALL	0x00323333	/* enable all interrupts mask */+#define TALITOS_IMR_HI_ERRONLY	0x00222222	/* enable error interrupts */+#define TALITOS_ISR		0x1010		/* interrupt status register */+#define TALITOS_ISR_ERROR	0x00010faa	/* errors mask */+#define TALITOS_ISR_DONE	0x00000055	/* channel(s) done mask */+#define TALITOS_ISR_HI		0x1014		/* interrupt status register */+#define TALITOS_ICR		0x1018		/* interrupt clear register */+#define TALITOS_ICR_HI		0x101C		/* interrupt clear register */++/* channel register address stride */+#define TALITOS_CH_OFFSET	0x100++/* channel register offset addresses and bits */+#define TALITOS_CH_CCCR		0x1108	/* Crypto-Channel Config Register */+#define TALITOS_CH_CCCR_RESET	0x1	/* Channel Reset bit */+#define TALITOS_CH_CCCR_HI	0x110c	/* Crypto-Channel Config Register */+#define TALITOS_CH_CCCR_HI_CDWE	0x10	/* Channel done writeback enable bit */+#define TALITOS_CH_CCCR_HI_NT	0x4	/* Notification type bit */+#define TALITOS_CH_CCCR_HI_CDIE	0x2	/* Channel Done Interrupt Enable bit */+#define TALITOS_CH_CCPSR	0x1110	/* Crypto-Channel Pointer Status Reg */+#define TALITOS_CH_CCPSR_HI	0x1114	/* Crypto-Channel Pointer Status Reg */+#define TALITOS_CH_FF		0x1148	/* Fetch FIFO */+#define TALITOS_CH_FF_HI	0x114c	/* Fetch FIFO's FETCH_ADRS */+#define TALITOS_CH_CDPR		0x1140	/* Crypto-Channel Pointer Status Reg */+#define TALITOS_CH_CDPR_HI	0x1144	/* Crypto-Channel Pointer Status Reg */+#define TALITOS_CH_DESCBUF	0x1180	/* (thru 11bf) Crypto-Channel +					 * Descriptor Buffer (debug) */++/* execution unit register offset addresses and bits */+#define TALITOS_DEUSR		0x2028	/* DEU status register */+#define TALITOS_DEUSR_HI	0x202c	/* DEU status register */+#define TALITOS_DEUISR		0x2030	/* DEU interrupt status register */+#define TALITOS_DEUISR_HI	0x2034	/* DEU interrupt status register */+#define TALITOS_DEUICR		0x2038	/* DEU interrupt control register */+#define TALITOS_DEUICR_HI	0x203c	/* DEU interrupt control register */+#define TALITOS_AESUISR		0x4030	/* AESU interrupt status register */+#define TALITOS_AESUISR_HI	0x4034	/* AESU interrupt status register */+#define TALITOS_AESUICR		0x4038	/* AESU interrupt control register */+#define TALITOS_AESUICR_HI	0x403c	/* AESU interrupt control register */+#define TALITOS_MDEUISR		0x6030	/* MDEU interrupt status register */+#define TALITOS_MDEUISR_HI	0x6034	/* MDEU interrupt status register */+#define TALITOS_RNGSR		0xa028	/* RNG status register */+#define TALITOS_RNGSR_HI	0xa02c	/* RNG status register */+#define TALITOS_RNGSR_HI_RD	0x1	/* RNG Reset done */+#define TALITOS_RNGSR_HI_OFL	0xff0000/* number of dwords in RNG output FIFO*/+#define TALITOS_RNGDSR		0xa010	/* RNG data size register */+#define TALITOS_RNGDSR_HI	0xa014	/* RNG data size register */+#define TALITOS_RNG_FIFO	0xa800	/* RNG FIFO - pool of random numbers */+#define TALITOS_RNGISR		0xa030	/* RNG Interrupt status register */+#define TALITOS_RNGISR_HI	0xa034	/* RNG Interrupt status register */+#define TALITOS_RNGRCR		0xa018	/* RNG Reset control register */+#define TALITOS_RNGRCR_HI	0xa01c	/* RNG Reset control register */+#define TALITOS_RNGRCR_HI_SR	0x1	/* RNG RNGRCR:Software Reset */++/* descriptor pointer entry */+struct talitos_desc_ptr {+	u16	len;		/* length */+	u8	extent;		/* jump (to s/g link table) and extent */+	u8	res;		/* reserved */+	u32	ptr;		/* pointer */+};++/* descriptor */+struct talitos_desc {+	u32	hdr;				/* header */+	u32	res;				/* reserved */+	struct talitos_desc_ptr		ptr[7];	/* ptr/len pair array */+};++/* talitos descriptor header (hdr) bits */++/* primary execution unit select */+#define	TALITOS_SEL0_AFEU	0x10000000+#define	TALITOS_SEL0_DEU	0x20000000+#define	TALITOS_SEL0_MDEU	0x30000000+#define	TALITOS_SEL0_RNG	0x40000000+#define	TALITOS_SEL0_PKEU	0x50000000+#define	TALITOS_SEL0_AESU	0x60000000++/* primary execution unit mode (MODE0) and derivatives */+#define	TALITOS_MODE0_AESU_CBC		0x00200000+#define	TALITOS_MODE0_AESU_ENC		0x00100000+#define	TALITOS_MODE0_DEU_CBC		0x00400000+#define	TALITOS_MODE0_DEU_3DES		0x00200000+#define	TALITOS_MODE0_DEU_ENC		0x00100000+#define	TALITOS_MODE0_MDEU_INIT		0x01000000	/* init starting regs */+#define	TALITOS_MODE0_MDEU_HMAC		0x00800000+#define	TALITOS_MODE0_MDEU_PAD		0x00400000	/* PD */+#define	TALITOS_MODE0_MDEU_MD5		0x00200000+#define	TALITOS_MODE0_MDEU_SHA256	0x00100000+#define	TALITOS_MODE0_MDEU_SHA1		0x00000000	/* SHA-160 */+#define	TALITOS_MODE0_MDEU_MD5_HMAC	\+		(TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)+#define	TALITOS_MODE0_MDEU_SHA256_HMAC	\+		(TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)+#define	TALITOS_MODE0_MDEU_SHA1_HMAC	\+		(TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)++/* secondary execution unit select (SEL1) */+/* it's MDEU or nothing */+#define	TALITOS_SEL1_MDEU	0x00030000++/* secondary execution unit mode (MODE1) and derivatives */+#define	TALITOS_MODE1_MDEU_INIT		0x00001000	/* init starting regs */+#define	TALITOS_MODE1_MDEU_HMAC		0x00000800+#define	TALITOS_MODE1_MDEU_PAD		0x00000400	/* PD */+#define	TALITOS_MODE1_MDEU_MD5		0x00000200+#define	TALITOS_MODE1_MDEU_SHA256	0x00000100+#define	TALITOS_MODE1_MDEU_SHA1		0x00000000	/* SHA-160 */+#define	TALITOS_MODE1_MDEU_MD5_HMAC	\+	(TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)+#define	TALITOS_MODE1_MDEU_SHA256_HMAC	\+	(TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)+#define	TALITOS_MODE1_MDEU_SHA1_HMAC	\+	(TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)++/* direction of overall data flow (DIR) */+#define	TALITOS_DIR_OUTBOUND	0x00000000+#define	TALITOS_DIR_INBOUND	0x00000002++/* done notification (DN) */+#define	TALITOS_DONE_NOTIFY	0x00000001++/* descriptor types */+/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */+#define TD_TYPE_AESU_CTR_NONSNOOP	(0 << 3)+#define TD_TYPE_IPSEC_ESP		(1 << 3)+#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU	(2 << 3)+#define TD_TYPE_HMAC_SNOOP_NO_AFEU	(4 << 3)++#define TALITOS_HDR_DONE_BITS	0xff000000++#define	DPRINTF(a...)	do { \+						if (debug) { \+							printk("%s: ", sc ? \+								device_get_nameunit(sc->sc_cdev) : "talitos"); \+							printk(a); \+						} \+					} while (0)diff -Nur linux-2.6.36.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.36/crypto/ocf/talitos/talitos_soft.h--- linux-2.6.36.orig/crypto/ocf/talitos/talitos_soft.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/talitos/talitos_soft.h	2010-11-09 20:28:13.272495451 +0100@@ -0,0 +1,77 @@+/*+ * Freescale SEC data structures for integration with ocf-linux+ *+ * Copyright (c) 2006 Freescale Semiconductor, Inc.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ *+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. The name of the author may not be used to endorse or promote products+ *    derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */++/*+ * paired descriptor and associated crypto operation+ */+struct desc_cryptop_pair {+	struct talitos_desc	cf_desc;	/* descriptor ptr */+	struct cryptop		*cf_crp;	/* cryptop ptr */+};++/*+ * Holds data specific to a single talitos device.+ */+struct talitos_softc {+	softc_device_decl	sc_cdev;+	struct platform_device	*sc_dev;	/* device backpointer */+	ocf_iomem_t		sc_base_addr;+	int			sc_irq;+	int			sc_num;		/* if we have multiple chips */+	int32_t			sc_cid;		/* crypto tag */+	u64			sc_chiprev;	/* major/minor chip revision */+	int			sc_nsessions;+	struct talitos_session	*sc_sessions;+	int			sc_num_channels;/* number of crypto channels */+	int			sc_chfifo_len;	/* channel fetch fifo len */+	int			sc_exec_units;	/* execution units mask */+	int			sc_desc_types;	/* descriptor types mask */+	/*+	 * mutual exclusion for intra-channel resources, e.g. fetch fifos+	 * the last entry is a meta-channel lock used by the channel scheduler+	 */+	spinlock_t		*sc_chnfifolock;+	/* sc_chnlastalgo contains last algorithm for that channel */+	int			*sc_chnlastalg;+	/* sc_chnfifo holds pending descriptor--crypto operation pairs */+	struct desc_cryptop_pair	**sc_chnfifo;+};++struct talitos_session {+	u_int32_t	ses_used;+	u_int32_t	ses_klen;		/* key length in bits */+	u_int32_t	ses_key[8];		/* DES/3DES/AES key */+	u_int32_t	ses_hmac[5];		/* hmac inner state */+	u_int32_t	ses_hmac_len;		/* hmac length */+	u_int32_t	ses_iv[4];		/* DES/3DES/AES iv */+	u_int32_t	ses_mlen;		/* desired hash result len (12=ipsec or 16) */+};++#define	TALITOS_SESSION(sid)	((sid) & 0x0fffffff)+#define	TALITOS_SID(crd, sesn)	(((crd) << 28) | ((sesn) & 0x0fffffff))diff -Nur linux-2.6.36.orig/crypto/ocf/uio.h linux-2.6.36/crypto/ocf/uio.h--- linux-2.6.36.orig/crypto/ocf/uio.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/crypto/ocf/uio.h	2010-11-09 20:28:13.313482727 +0100@@ -0,0 +1,54 @@+#ifndef _OCF_UIO_H_+#define _OCF_UIO_H_++#include <linux/uio.h>++/*+ * The linux uio.h doesn't have all we need.  To be fully api compatible+ * with the BSD cryptodev,  we need to keep this around.  Perhaps this can+ * be moved back into the linux/uio.h+ *+ * Linux port done by David McCullough <david_mccullough@mcafee.com>+ * Copyright (C) 2006-2010 David McCullough+ * Copyright (C) 2004-2005 Intel Corporation.+ *+ * LICENSE TERMS+ *+ * The free distribution and use of this software in both source and binary+ * form is allowed (with or without changes) provided that:+ *+ *   1. distributions of this source code include the above copyright+ *      notice, this list of conditions and the following disclaimer;+ *+ *   2. distributions in binary form include the above copyright+ *      notice, this list of conditions and the following disclaimer+ *      in the documentation and/or other associated materials;+ *+ *   3. the copyright holder's name is not used to endorse products+ *      built using this software without specific written permission.+ *+ * ALTERNATIVELY, provided that this notice is retained in full, this product+ * may be distributed under the terms of the GNU General Public License (GPL),+ * in which case the provisions of the GPL apply INSTEAD OF those given above.+ *+ * DISCLAIMER+ *+ * This software is provided 'as is' with no explicit or implied warranties+ * in respect of its properties, including, but not limited to, correctness+ * and/or fitness for purpose.+ * ---------------------------------------------------------------------------+ */++struct uio {+	struct	iovec *uio_iov;+	int		uio_iovcnt;+	off_t	uio_offset;+	int		uio_resid;+#if 0+	enum	uio_seg uio_segflg;+	enum	uio_rw uio_rw;+	struct  thread *uio_td;+#endif+};++#endifdiff -Nur linux-2.6.36.orig/drivers/char/random.c linux-2.6.36/drivers/char/random.c--- linux-2.6.36.orig/drivers/char/random.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/drivers/char/random.c	2010-11-09 20:28:13.352495461 +0100@@ -129,6 +129,9 @@  *                                unsigned int value);  * 	void add_interrupt_randomness(int irq);  *+ *      void random_input_words(__u32 *buf, size_t wordcount, int ent_count)+ *      int random_input_wait(void);+ *  * add_input_randomness() uses the input layer interrupt timing, as well as  * the event type information from the hardware.  *@@ -140,6 +143,13 @@  * a better measure, since the timing of the disk interrupts are more  * unpredictable.  *+ * random_input_words() just provides a raw block of entropy to the input+ * pool, such as from a hardware entropy generator.+ *+ * random_input_wait() suspends the caller until such time as the+ * entropy pool falls below the write threshold, and returns a count of how+ * much entropy (in bits) is needed to sustain the pool.+ *  * All of these routines try to estimate how many bits of randomness a  * particular randomness source.  They do this by keeping track of the  * first and second order deltas of the event timings.@@ -259,6 +269,7 @@ #define SEC_XFER_SIZE 512 #define EXTRACT_SIZE 10 + /*  * The minimum number of bits of entropy before we wake up a read on  * /dev/random.  Should be enough to do a significant reseed.@@ -552,6 +563,60 @@ 	spin_unlock_irqrestore(&r->lock, flags); } +/*+ * random_input_words - add bulk entropy to pool+ *+ * @buf: buffer to add+ * @wordcount: number of __u32 words to add+ * @ent_count: total amount of entropy (in bits) to credit+ *+ * this provides bulk input of entropy to the input pool+ *+ */+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)+{+	mix_pool_bytes(&input_pool, buf, wordcount*4);++	credit_entropy_bits(&input_pool, ent_count);++	DEBUG_ENT("crediting %d bits => %d\n",+		  ent_count, input_pool.entropy_count);+	/*+	 * Wake up waiting processes if we have enough+	 * entropy.+	 */+	if (input_pool.entropy_count >= random_read_wakeup_thresh)+ 		wake_up_interruptible(&random_read_wait);+}+EXPORT_SYMBOL(random_input_words);++/*+ * random_input_wait - wait until random needs entropy+ *+ * this function sleeps until the /dev/random subsystem actually+ * needs more entropy, and then return the amount of entropy+ * that it would be nice to have added to the system.+ */+int random_input_wait(void)+{+	int count;++	wait_event_interruptible(random_write_wait, +			 input_pool.entropy_count < random_write_wakeup_thresh);++	count = random_write_wakeup_thresh - input_pool.entropy_count;++        /* likely we got woken up due to a signal */+	if (count <= 0) count = random_read_wakeup_thresh; ++	DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",+		  count,+		  input_pool.entropy_count, random_write_wakeup_thresh);++	return count;+}+EXPORT_SYMBOL(random_input_wait);+ /*********************************************************************  *  * Entropy input managementdiff -Nur linux-2.6.36.orig/fs/fcntl.c linux-2.6.36/fs/fcntl.c--- linux-2.6.36.orig/fs/fcntl.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/fs/fcntl.c	2010-11-09 20:28:13.392495458 +0100@@ -142,6 +142,7 @@ 	} 	return ret; }+EXPORT_SYMBOL(sys_dup);  #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) diff -Nur linux-2.6.36.orig/include/linux/miscdevice.h linux-2.6.36/include/linux/miscdevice.h--- linux-2.6.36.orig/include/linux/miscdevice.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/include/linux/miscdevice.h	2010-11-09 20:28:13.432495492 +0100@@ -18,6 +18,7 @@ #define APOLLO_MOUSE_MINOR	7 #define PC110PAD_MINOR		9 /*#define ADB_MOUSE_MINOR	10	FIXME OBSOLETE */+#define CRYPTODEV_MINOR		70	/* /dev/crypto */ #define WATCHDOG_MINOR		130	/* Watchdog timer     */ #define TEMP_MINOR		131	/* Temperature Sensor */ #define RTC_MINOR		135diff -Nur linux-2.6.36.orig/include/linux/random.h linux-2.6.36/include/linux/random.h--- linux-2.6.36.orig/include/linux/random.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/include/linux/random.h	2010-11-09 20:28:13.597270121 +0100@@ -9,6 +9,7 @@  #include <linux/types.h> #include <linux/ioctl.h>+#include <linux/types.h> /* for __u32 in user space */ #include <linux/irqnr.h>  /* ioctl()'s for the random number generator */@@ -34,6 +35,30 @@ /* Clear the entropy pool and associated counters.  (Superuser only.) */ #define RNDCLEARPOOL	_IO( 'R', 0x06 ) +#ifdef CONFIG_FIPS_RNG++/* Size of seed value - equal to AES blocksize */+#define AES_BLOCK_SIZE_BYTES	16+#define SEED_SIZE_BYTES			AES_BLOCK_SIZE_BYTES+/* Size of AES key */+#define KEY_SIZE_BYTES		16++/* ioctl() structure used by FIPS 140-2 Tests */+struct rand_fips_test {+	unsigned char key[KEY_SIZE_BYTES];			/* Input */+	unsigned char datetime[SEED_SIZE_BYTES];	/* Input */+	unsigned char seed[SEED_SIZE_BYTES];		/* Input */+	unsigned char result[SEED_SIZE_BYTES];		/* Output */+};++/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */+#define RNDFIPSVST	_IOWR('R', 0x10, struct rand_fips_test)++/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */+#define RNDFIPSMCT	_IOWR('R', 0x11, struct rand_fips_test)++#endif /* #ifdef CONFIG_FIPS_RNG */+ struct rand_pool_info { 	int	entropy_count; 	int	buf_size;@@ -54,6 +79,10 @@ 				 unsigned int value); extern void add_interrupt_randomness(int irq); +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);+extern int random_input_wait(void);+#define HAS_RANDOM_INPUT_WAIT 1+ extern void get_random_bytes(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); 
 |